android 关于屏幕适配的整理

         之前看到一篇文章,说UI给的切图是1280x720这个分辨率的,给的标注单位是px(像素)。把图片放在drawable-xhdpi中,然后开始调整布局(当时默认1dp=2px)。把这个布局放到一个720P的电视上,发现完全变形了,看了下电视的density,发现这货是1,这是一个mdpi的设备!

          然后我就开始想了,720P的切图,要放在xhdpi这里,但是有的设备自身是mdpi之类的,那这个分辨率和dpi到底是什么关系?

我们先来了解下分辨率和像素:

                DPI:每英寸像素数

          简单的屏幕分辨率计算方法:

                DisplayMetrics metrics = this.getResources().getDisplayMetrics();
                float density = metrics.density;
                int dpi = metrics.densityDpi;
                int heightPixels = metrics.heightPixels;
                int widthPixels = metrics.widthPixels;

              Log.e("---metrics---", "比例:"+density+",dpi:"+dpi+",高像素:"+heightPixels+",宽像素:"+widthPixels);

这个屏幕高度是不包含虚拟按键的高度,如果要带上虚拟按键的总高度可以这样

    /**
     * 通过反射,获取包含虚拟键的整体屏幕高度
     *
     * @return
     */
    private int getHasVirtualKey() {
        int height = 0;
        Display display = getWindowManager().getDefaultDisplay();
        DisplayMetrics dm = new DisplayMetrics();
        @SuppressWarnings("rawtypes")
        Class c;
        try {
            c = Class.forName("android.view.Display");
            @SuppressWarnings("unchecked")
            Method method = c.getMethod("getRealMetrics", DisplayMetrics.class);
            method.invoke(display, dm);
            height = dm.heightPixels;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return height;
    }

最小屏幕宽度:160*屏幕宽度像素/dpi

名称dpi屏幕密度图片icon尺寸
drawable-ldpi120density=0.7536*36
drawable-mdpi160density=1(baseline)48*48
drawable-hdpi240density=1.572*72
drawable-xhdpi320density=296*96
drawable-xxhdpi480density=3144*144
drawable-xxxhdpi640density=4192*192

注:Android studio mipmap文件夹只存放启动图标icon


1.为什么一个720P的设备,取mdpi里的图片,但是720P的切图要放在xhdpi里?

A: 这完全是根据主流手机来决定的,比如现在主流的是480P/hdpi的手机,那么,在做UI时,就会取720P作为xhdpi,取320P作为mdpi,取240P作为ldpi,这样一套套图就切出来了。

如果,主流的手机分辨率变成了720P/hdpi的手机,那么,在做UI时,就会取480P作为mdpi,取1080P作为xhdpi,以此类推。

至于Google是这样推荐的:取你手边最大的分辨率作为基准,做出最清晰的图(xhdpi),然后,按比例缩放,做出hdpi、mdpi和ldpi。所以从原理上,720P的切图放在哪里是可以根据设备来变换的。


2.如果720P的切图在xhdpi里,但我手头有一个mdpi/720P的设备,那怎么办呢?

(假设你的应用要支持所有奇葩的分辨率,而且你已经切好了4套图(ldpi~xhdpi)  并在layout里写了一套布局)

A: 如果你自己思考了dpi和分辨率的关系的话,你会发现,他们的关系就是没有关系...所以这个问题,我的解决办法(大家的)是,让多套dimens来帮我们解决这个问题。

 480p600p720p1080p
mdpivalues-sw480dp-mdpivalues-sw600dp-mdpivalues-sw720dp-mdpivalues-sw1080dp-mdpi
hdpivalues-sw480dp-hdpi
xhdpivalues-sw480dp-xhdpi
在你的res文件夹下,新建这些文件夹,然后再放进一个dimens.xml,用这种方法,就可以应对所有的分辨率情况了。

举例说明下:如果原图(1280x720)上有一个100x50(像素)大小的控件,那么对于一个正常的hdpi/800x480的设备来说,应该设置它的大小(dp)为:

长:(100/720*480/1.5)dp = 45dp (向上取整)

宽:(50/720*480/1.5)dp = 23dp

将这两个值写在values-sw480dp-hdpi/dimens.xml里,图的比例和原图就一样了。


那对于一个刚才我列举到的mdpi/1280x720的设备,它的大小应该是:

长:(100/720*720/1) = 100dp;

宽:(50/720*720/1) = 50dp;

将这两个值写在values-sw720dp-mdpi中,图的比例和原图就一样了。



还有个大佬写的自适应屏幕的东西,不过已经停止维护了

GitHub地址:https://github.com/hongyangAndroid/AndroidAutoLayout


这是关于计算手机最小宽度(以dp为单位)

最近在开发中遇到屏幕适配的问题:都是使用dp为单位,出来的效果却不一样。 
对比手机:  

屏幕对比 

两个手机屏幕尺寸相同,都是5.7英寸,同样画100dp的线,在屏幕上的长度却不一样,Note5上显示的要短一些。

原因为两个手机最小宽度(以dp为单位)不同。

怎样计算

安卓根据手机ppi设置dpi,分为 120(ldpi)、160(mdpi)、213、240(hdpi)、280、320(xhdpi)、360、400、420、480(xxhdpi)、560、640(xxxhdpi); 
根据DisplayMetrics可以获取到手机dpi,Note5比较特殊为560(ppi为515),A8为480(ppi为386)。 

所以

Note5 dp=160*1440/560=411
A8 dp=160*1080/480=360

怎样解决

安卓会自动根据手机的大小(按宽度算 dp为单位)去选择values或者values-swxxxdp。 
sw为small width,后面接的值表示,屏幕的最小宽度dp大于这个值的时候启用。 
所以写了两个dimens.xml分别放在 
res/values/dimens.xml 
res/values-sw400dp/dimens.xml 
Note5会找values-sw400dp/dimens.xml,A8会找默认的values/dimens.xml;

默认的总宽度为360dp,放在values/dimens.xml文件中:


<resources>
    <dimen name="DIMEN_1dp">1dp</dimen>
    <dimen name="DIMEN_2dp">2dp</dimen>
    <dimen name="DIMEN_3dp">3dp</dimen>
    <dimen name="DIMEN_5dp">5dp</dimen>
    <dimen name="DIMEN_6dp">6dp</dimen>
    <dimen name="DIMEN_7dp">7dp</dimen>
    <dimen name="DIMEN_8dp">8dp</dimen>
    <dimen name="DIMEN_10dp">10dp</dimen>
    <dimen name="DIMEN_11dp">11dp</dimen>
    <dimen name="DIMEN_12dp">12dp</dimen>
    <dimen name="DIMEN_13dp">13dp</dimen>
    <dimen name="DIMEN_14dp">14dp</dimen>
    <dimen name="DIMEN_15dp">15dp</dimen>
    <dimen name="DIMEN_16dp">16dp</dimen>
    <dimen name="DIMEN_18dp">18dp</dimen>
    <dimen name="DIMEN_20dp">20dp</dimen>
    <dimen name="DIMEN_22dp">22dp</dimen>
    <dimen name="DIMEN_24dp">24dp</dimen>
    <dimen name="DIMEN_26dp">26dp</dimen>
    <dimen name="DIMEN_30dp">30dp</dimen>
    <dimen name="DIMEN_32dp">32dp</dimen>
    <dimen name="DIMEN_36dp">36dp</dimen>
    <dimen name="DIMEN_40dp">40dp</dimen>
    <dimen name="DIMEN_42dp">42dp</dimen>
    <dimen name="DIMEN_45dp">45dp</dimen>
    <dimen name="DIMEN_46dp">46dp</dimen>
    <dimen name="DIMEN_50dp">50dp</dimen>
    <dimen name="DIMEN_52dp">52dp</dimen>
    <dimen name="DIMEN_60dp">60dp</dimen>
    <dimen name="DIMEN_65dp">65dp</dimen>
    <dimen name="DIMEN_70dp">70dp</dimen>
    <dimen name="DIMEN_80dp">80dp</dimen>
    <dimen name="DIMEN_90dp">90dp</dimen>
    <dimen name="DIMEN_100dp">100dp</dimen>
    <dimen name="DIMEN_120dp">120dp</dimen>
    <dimen name="DIMEN_130dp">130dp</dimen>
    <dimen name="DIMEN_150dp">150dp</dimen>
    <dimen name="DIMEN_190dp">190dp</dimen>
    <dimen name="DIMEN_200dp">200dp</dimen>
    <dimen name="DIMEN_240dp">240dp</dimen>
    <dimen name="DIMEN_250dp">250dp</dimen>
    <dimen name="DIMEN_255dp">255dp</dimen>
    <dimen name="DIMEN_300dp">300dp</dimen>
</resources>
411dp的宽度呢?由于411和360是1.14倍的关系,所以 DIMEN_1dp = 1.14dp
<resources>
    <!-- 这里用的1.2,应该是1.14 -->
    <dimen name="DIMEN_1dp">1.2dp</dimen>
    <dimen name="DIMEN_2dp">2.4dp</dimen>
    <dimen name="DIMEN_3dp">4.8dp</dimen>
    <dimen name="DIMEN_5dp">6dp</dimen>
    <dimen name="DIMEN_6dp">7.2dp</dimen>
    <dimen name="DIMEN_7dp">8.4dp</dimen>
    <dimen name="DIMEN_8dp">9.6dp</dimen>
    <dimen name="DIMEN_10dp">12dp</dimen>
    <dimen name="DIMEN_11dp">13.2dp</dimen>
    <dimen name="DIMEN_12dp">14.4dp</dimen>
    <dimen name="DIMEN_13dp">15.6dp</dimen>
    <dimen name="DIMEN_14dp">16.8dp</dimen>
    <dimen name="DIMEN_15dp">18dp</dimen>
    <dimen name="DIMEN_16dp">19.2dp</dimen>
    <dimen name="DIMEN_18dp">21.6dp</dimen>
    <dimen name="DIMEN_20dp">24dp</dimen>
    <dimen name="DIMEN_22dp">26.4dp</dimen>
    <dimen name="DIMEN_24dp">28.8dp</dimen>
    <dimen name="DIMEN_26dp">31.2dp</dimen>
    <dimen name="DIMEN_30dp">36dp</dimen>
    <dimen name="DIMEN_32dp">38.4dp</dimen>
    <dimen name="DIMEN_36dp">43.2dp</dimen>
    <dimen name="DIMEN_40dp">48dp</dimen>
    <dimen name="DIMEN_42dp">50.4dp</dimen>
    <dimen name="DIMEN_45dp">54dp</dimen>
    <dimen name="DIMEN_46dp">55.2dp</dimen>
    <dimen name="DIMEN_50dp">60dp</dimen>
    <dimen name="DIMEN_52dp">62.4dp</dimen>
    <dimen name="DIMEN_60dp">72dp</dimen>
    <dimen name="DIMEN_65dp">78dp</dimen>
    <dimen name="DIMEN_70dp">84dp</dimen>
    <dimen name="DIMEN_80dp">96dp</dimen>
    <dimen name="DIMEN_90dp">108dp</dimen>
    <dimen name="DIMEN_100dp">120dp</dimen>
    <dimen name="DIMEN_120dp">144dp</dimen>
    <dimen name="DIMEN_130dp">156dp</dimen>
    <dimen name="DIMEN_150dp">180dp</dimen>
    <dimen name="DIMEN_190dp">228dp</dimen>
    <dimen name="DIMEN_200dp">240dp</dimen>
    <dimen name="DIMEN_240dp">288dp</dimen>
    <dimen name="DIMEN_250dp">300dp</dimen>
    <dimen name="DIMEN_255dp">306dp</dimen>
    <dimen name="DIMEN_300dp">360dp</dimen>
</resources>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值