Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「Android 屏幕适配终结者」问题汇总 #758

Open
Blankj opened this issue Dec 17, 2018 · 75 comments
Open

「Android 屏幕适配终结者」问题汇总 #758

Blankj opened this issue Dec 17, 2018 · 75 comments
Assignees

Comments

@Blankj
Copy link
Owner

Blankj commented Dec 17, 2018

文章地址

Android 屏幕适配终结者

发现 BUG 的话首先试试升级到最新版本看是否解决了哦。

MIUI 在 Android 5.1.1 情况适配失效

MIUI 自己封装了一层 Resource,需要去修改它内部的 mTmpMetrics 来适配,这个 BUG 应该是基于修改 DisplayMetrics 都会存在的,升级到 1.22.6 版本即可。

@Blankj Blankj changed the title Android 屏幕适配终结者 issue 「Android 屏幕适配终结者」问题汇总 Dec 17, 2018
@Sum-sdl
Copy link

Sum-sdl commented Dec 18, 2018

AdaptScreenUtils提供适配宽度和高度2个方法,1080x1920尺寸,适配宽度1080,那View的高度是自动适配1920的高度吗?

@Blankj
Copy link
Owner Author

Blankj commented Dec 18, 2018

@Sum-sdl 适配是在某一维度上进行适配,另一维度一般是可滚动的,如果像你这么说两个纬度都固定了,那怎么可能做到适配,比如你宽度适配了,你又要适配高度,那不同宽高比的手机在某一维度肯定会存在变形的。

@jingzz1
Copy link

jingzz1 commented Dec 18, 2018

适配的话,需要把项目上的dp单位都改成pt吗?

@Blankj
Copy link
Owner Author

Blankj commented Dec 18, 2018

@jingzz1 不需要的啊,你从前的布局就别改动了,新的可以适配进来,老的你想改那也可以

@JessYanCoding
Copy link

JessYanCoding commented Dec 18, 2018

感谢 BlankJ 老师的分享,AndroidAutoSize 已经迭代 10 多个版本,扩展了很多自定义功能,基本能满足所有人的屏幕适配需求,唯一美中不足的就是屏幕适配在某些情况下可能会失效的问题,这一直困扰着 AndroidAutoSize 以及今日头条屏幕适配方案,之前我对于此问题提供了两种解决思路

第一个就是在布局显示到屏幕上之前,调用框架提供的方法将 DisplayMetrics 的参数恢复成期望的值,但必须保证调用这个方法到布局显示到屏幕的期间,DisplayMetrics 的参数不能被修改,由于某些定制系统的行为可能是未知的,所以就一直没找到一个最合适并且通用的调用时机

第二个就是寻求获得唯一修改 DisplayMetrics 的权限,让其他代码不能修改 DisplayMetrics,但这也只是构想,还没找到比较好的解决方案

今天看到 blankJ 老师的文章,恍然大悟,我第一个方案一直在寻找的最合适的调用时机,可能就是您的方案!

今日头条方案的切入点 TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics) 方法,需要传入一个 DisplayMetrics,而系统会在调用 TypedValue.applyDimension 之前通过 context.getResources() 获取 DisplayMetrics,所以重写 getResources 将 DisplayMetrics 的参数修改为正确的值,这样就可以极大的避免了 DisplayMetrics 的参数在布局显示到屏幕上之前被修改,我之前还是想太复杂,舍近求远,没有关注到这个这个核心切入点

不过这里还有一个疑虑,如果在调用 TypedValue.applyDimension 到布局显示到屏幕的期间,DisplayMetrics 的参数被其他未知代码修改,也还是会造成屏幕适配的失效,不过您的解决方案已经可以让稳定性提升一大步

最后感谢 BlankJ 老师的分享,文中的总结很到位,我们都是站在巨人的肩膀上,感谢开源,我们一起努力将会让今日头条屏幕适配方案更完美!

@45541926
Copy link

pt!=dp 为什么说关闭这个效果pt的效果==dp 这点不是很明白

@Blankj
Copy link
Owner Author

Blankj commented Dec 20, 2018

@45541926 所谓的关闭我还是对 pt 操作了,又不是原生的 1pt = 1/72 inch

@45541926
Copy link

@45541926 所谓的关闭我还是对 pt 操作了,又不是原生的 1pt = 1/72 inch

哦哦 懂了 ths

@hurshi
Copy link

hurshi commented Dec 20, 2018

果然强大呀,但有一事不解,如下代码:

     public static float applyDimension(int unit, float value, DisplayMetrics metrics) {
        switch (unit) {
            case COMPLEX_UNIT_PX:
                return value;
            case COMPLEX_UNIT_DIP:
                return value * metrics.density;
            case COMPLEX_UNIT_SP:
                return value * metrics.scaledDensity;
            case COMPLEX_UNIT_PT:
                return value * metrics.xdpi * (1.0f / 72);
            case COMPLEX_UNIT_IN:
                return value * metrics.xdpi;
            case COMPLEX_UNIT_MM:
                return value * metrics.xdpi * (1.0f / 25.4f);
        }
        return 0;
    }

不知为什么挑了 PT 呢,用 IN 不是还省的 *72了?

@Blankj
Copy link
Owner Author

Blankj commented Dec 20, 2018

pt 比较接近于 dp,inch、mm 都太大了

@Blankj
Copy link
Owner Author

Blankj commented Dec 21, 2018

@lcl6 你说的是什么意思?上个图吧,textview 内容无法对齐和我这适配有什么关系?是你自己设置的 gravity 不同啊

@Blankj Blankj self-assigned this Dec 25, 2018
@Blankj Blankj pinned this issue Dec 25, 2018
@Blankj Blankj unpinned this issue Dec 25, 2018
@Blankj Blankj pinned this issue Dec 25, 2018
@Blankj Blankj mentioned this issue Jan 25, 2019
@Blankj
Copy link
Owner Author

Blankj commented Feb 25, 2019

如果是悬浮窗适配,因为 inflate 用到的 context 是 application 级别的,所以需要在自定义的 Application 中重写 getResource。参考 #840

@chenxiaofei910714
Copy link

单个维度适配的话,那在一些全面屏手机上比如:1080*2280这个种情况下高度,控件的高度就变小了,有什么办法可以解决吗?

@Blankj
Copy link
Owner Author

Blankj commented Mar 7, 2019

单纬度是因为有一维度是可滚动的啊,怎么会变小呢,我 demo 有变小?
双维度适配岂不是只有一种屏幕比例啊,比如只有 16 : 9 比例,那你在 4 : 3 机器上肯定会变形啊。

@mufaith
Copy link

mufaith commented Mar 8, 2019

您好,问一下,如果我要在pad上适配的话,会有什么问题么

@Blankj
Copy link
Owner Author

Blankj commented Mar 8, 2019

@mufaith 和设备没关系的,只要是 android 就行

@Blankj
Copy link
Owner Author

Blankj commented Aug 22, 2019

@walkthehorizon 不推荐 dp 适配,会导致系统 View 大小出问题。

@wsyzj92
Copy link

wsyzj92 commented Sep 3, 2019

WX20190903-175917@2x

你好,请教一个问题。这一张是使用screen size 为30.6(1080 * 1920) 的预览效果 这个文字在预览的时候看着是真的别扭,比正常的明显小了好多,然后运行跑起来是没问题的。是不是我哪里设置错了,还是本来就这样的?谢谢。

WX20190903-175944@2x

这个是其他配置预览效果,这个是正确的。_ TextSize都是20sp的,没注意打错了,请忽略。

@Blankj
Copy link
Owner Author

Blankj commented Sep 4, 2019

@wsyzj92 如果你字体不想随系统字体改变而改变,那字体大小用 pt 即可,如果想采用 sp 的话,那就用 tools:textSize="xxpt" 来预览即可。

@wsyzj92
Copy link

wsyzj92 commented Sep 4, 2019

@Blankj 好的,明白了。

@rube520
Copy link

rube520 commented Sep 23, 2019

字体采用pt不能随系统改变,采用sp那不就是等于说字体不适配吗?这个很重要吧

@Blankj
Copy link
Owner Author

Blankj commented Sep 23, 2019

@rube520 谁规定应用字体就一定要用 sp 了,sp 只是能根据系统字体大小而改变罢了,有些应用就不想要这个随系统改变的功能,改变字体了 view 布局就出问题了,想用什么自己选择就好

@rube520
Copy link

rube520 commented Sep 24, 2019

重写application的getResources()方法会导致栈溢出。
@OverRide
public Resources getResources() {
//以pt为单位进行适配
if (ScreenUtils.isLandscape(this)){
return AdaptScreenUtils.adaptWidth(super.getResources(), 640, this);
} else {
return AdaptScreenUtils.adaptHeight(super.getResources(), 640, this);
}
// return super.getResources();
}

@magic0908
Copy link

感谢作者的开源库,关于屏幕适配我请教几个问题:
1、设计用的蓝湖,设计图是375667,计算(375375+667*667)开平方再除72约等于10.63,density为ldpi的,那是不是后面的icon资源需要下载对应ldpi尺寸,然后放在项目res的ldpi目录下?
2、接上个问题,只需要一套ldpi资源可以了吗?
3、开发的时候使用pt单位,如果后期需要更换其他适配方案,是不是每个xml的pt都需要修改?

@Blankj
Copy link
Owner Author

Blankj commented Dec 4, 2019

@magic0908 资源都是用一套尽可能高的 dpi 的呀,适配是百分比适配,你传入了适配宽度是 375,那你写 375 pt ,那在任何机器上展示都是全屏的宽度,你写 100pt,那占的就是 100/375 的宽度百分比,你要布局要用其他适配,那你就别用 pt 就行了,你用 dp 那些对 pt 都不会有影响。

@qinlei00
Copy link

为什么我单位只有设置成pt才生效是否,其他的适配都不生效。设置是按照教程的1080*1920设置的

@Blankj
Copy link
Owner Author

Blankj commented Dec 17, 2019

@qinlei00 好好看文章,文章里都说了是用 pt 适配,那你用其他单位肯定没啥用的

@qiaogaojian
Copy link

Application中重写getResources( )存在递归调用
image

@cyixlq

This comment has been minimized.

@BigBigDeBoy
Copy link

在一个activity页面(添加了 android:configChanges="orientation|screenSize|keyboardHidden")的RecyclerView的item里使用,当旋转屏幕触发onConfigurationChanged的时候,某些item出现尺寸适配失效。

@nwhhades 解决了吗

@zhang-yanpeng
Copy link

zhang-yanpeng commented Sep 16, 2020

device-2020-09-16-152142
页面A 指定了横屏,但是进入之后 会先进入页面B(竖屏),从B返回了A,这时候,A适配错乱了,这种情况有解决方案么?

@zhang-yanpeng
Copy link

在一个activity页面(添加了 android:configChanges="orientation|screenSize|keyboardHidden")的RecyclerView的item里使用,当旋转屏幕触发onConfigurationChanged的时候,某些item出现尺寸适配失效。

@nwhhades 解决了吗
我也遇到了这个问题,解决了么

@junixapp
Copy link

junixapp commented Dec 23, 2020

适配后,用的一些三方库单位还是dp,会显得很小,怎么解决?
@Blankj

@VolleyCN
Copy link

VolleyCN commented Jan 8, 2021

适配后,当app页面在横屏模式下,按下home键,app在后台运行时刷新ui,会适配失效,@Blankj
已解决 ScreenUtils.isPortrait()在app进入后台后,横屏页面获取依然返回的true导致
适配判断横竖屏应用Activity里的Resources配置里的屏幕方向
@OverRide
public Resources getResources() {
if (isPortrait()) {
return AdaptScreenUtils.adaptWidth(super.getResources(), InitManager.BASE_SIZE_IN_DP);
} else {
return AdaptScreenUtils.adaptHeight(super.getResources(), InitManager.BASE_SIZE_IN_DP);
}
}

public boolean isPortrait() {
    return super.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
}

@Andun084
Copy link

Andun084 commented Jan 9, 2021 via email

@Andun084
Copy link

Andun084 commented Jan 9, 2021 via email

@Andun084
Copy link

Andun084 commented Jan 9, 2021 via email

@mjsheng
Copy link

mjsheng commented Jan 16, 2021

蓝湖上设计图尺寸 dp 和 pt 都是 414 ✖️ 896,px是1242 ✖️ 2688。我现在页面用dp,字体用sp,图片放在xxxhdpi 。那么我接入适配用
AdaptScreenUtils.adaptWidth(super.getResources(), 414) 还是
AdaptScreenUtils.adaptWidth(super.getResources(), 1242)
我两个都试了,效果一样😂
还有接入后单位还可以用dp sp吗,还是统一用 pt
谢谢🌹

@bytebubbles
Copy link

bytebubbles commented Aug 19, 2021

用这个方法适配的app,在华为多任务的小窗口上适配失效

@zhaoxiuyu
Copy link

@bytebubbles 用作者Demo APP试过 确实是失效的,

@wycnet
Copy link

wycnet commented Mar 17, 2022

老哥,请教一个问题。 如果我想自定义系统的布局选择 例如:layout-land 、layout-port 。 我自定义layout-xxx ,并定义屏幕尺寸的选择规则,请问要从哪方面入手呢?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests