您当前的位置: 首页 >  android

Kevin-Dev

暂无认证

  • 3浏览

    0关注

    544博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Android 项目必备(十)--> 屏幕适配

Kevin-Dev 发布时间:2017-09-07 11:19:01 ,浏览量:3

在这里插入图片描述

文章目录
      • 定义
      • 常见设备的 dp、px、density 的关系
      • 常见适配方法
      • 常用适配框架
      • 推荐文章

推荐1倍效果图,即采用 720 * 360 大小( 1280 *720:两倍图 \ 1920 * 1080: 三倍图),最主要的原因就是1px = 1dp,效果图标多大的 px,布局就写多大 dp。

定义
  • 像素 - px: 一个小黑点就是像素。

  • 尺寸: 屏幕的对角线的长度。

  • 分辨率: 整个屏幕一共有多少个点,也就是像素。

  • 像素密度 - dpi:

  1. 每英寸中的像素数。
  2. 假如设备分辨率为320*240,屏幕长2英寸宽1.5英寸,dpi=320/2 = 240/1.5 =160。
  3. 对应于DisplayMetrics类中属性densityDpi的值。
  4. 当然这种宽和高的dpi都相同的情况现在已经很少见。
  • 设备独立像素 - dip - dp: 1.不同设备有不同的显示效果,不依赖像素。 2.dp = px / density 3.dp = px / (dpi / 160) 4.dpi(像素密度)为160 的设备上1dp = 1px。

  • 放大像素 - sp: 用于字体显示。

  • dp转px、px转dp

public class Dp2Px {
    public static int dp2px(Context context, int dp) {
        return (int) (dp * context.getResources().getDisplayMetrics().density + 0.5);
    }

    public static int px2dp(Context context, int px) {
        return (int) (px / context.getResources().getDisplayMetrics().density + 0.5);
    }
}
常见设备的 dp、px、density 的关系
  • ldpi:
density:0.75
分辨率:240*320 
关系:dp = px / 0.75
  • mdpi:
density:1
分辨率:320 * 480
关系:dp = px / 1
  • hdpi:
density:1.5
分辨率:480 * 800
关系:dp = px / 1.5
  • xhdpi:
density:2.0
分辨率:720 * 1280 
关系:dp = px / 2
  • xxhdpi:
density:3
分辨率:1080 * 1920 
关系:dp = px / 3
  • 获取参数
//以1280*720为基准:
//获取手机屏幕的宽和高
int widthPixels = getResources().getDisplayMetrics().widthPixels;
int heightPixels = getResources().getDisplayMetrics().heightPixels;
//density
float density = getResources().getDisplayMetrics().density;
//dpi
int densityDpi = getResources().getDisplayMetrics().densityDpi;
//1dp = 多少px
int px = Dp2Px.dp2px(this, 1);
//1px  = 多少dp
int dp = Dp2Px.px2dp(this, 1);

输出结果:

E/MainActivity: widthPixels: 720
E/MainActivity: heightPixels: 1280
E/MainActivity: density: 2.0
E/MainActivity: densityDpi: 320
E/MainActivity: px:2
E/MainActivity: dp:1
常见适配方法

1. 图片适配 1.1 图片的查找顺序

  • 注意:一般手机 ldpi120dip 220dip 80dip 2.在布局文件中引用 3.新建需要适配的values-XXX(比如values-1280x720,注意规范大值在前) 4.在新建values-1280x720中的dimens.xml文件中 * 180dp 5.所有手机适配找对应的默认的dimens * 思考:如何计算dpi?如何计算手机密度比?能够用dp适配所有手机吗? * dp不能适配所有手机; * 举个例子:按钮占屏幕宽度一半,把宽度设置成160dp,120px和160px和240px可以占屏幕一半,但是360px则小于屏幕一半; * 如果把宽度设置成180dp,那么360dp可以占屏幕一半,但其他几个又不行。 * 如果要适配所有手机的控件宽度为屏幕宽度的一半,该怎么做呢?用dimen 常用适配框架

    今日头条适配

    1) 添加依赖

    allprojects {
        repositories {
            ...
            maven { url "https://jitpack.io" }
        }
    }
    ------------------------------------------------------
    implementation 'me.jessyan:autosize:1.2.1'
    

    2) 基本使用 AndroidAutoSize 在使用上非常简单,只需要填写设计图尺寸这一步即可接入项目;

    
            
            ...
            
                  
            ...
                    
    
    

    有两种类型的布局单位可以选择,一个是 主单位 (dp、sp),一个是 副单位 (pt、in、mm)

    • 主单位: 使用 dp、sp 为单位进行布局,侵入性最低,会影响其他三方库页面、三方库控件以及系统控件的布局效果,但 AndroidAutoSize 也通过这个特性,使用 ExternalAdaptManager 实现了在不修改三方库源码的情况下适配三方库的功能
    • 副单位: 使用 pt、in、mm 为单位进行布局,侵入性高,对老项目的支持比较好,不会影响其他三方库页面、三方库控件以及系统控件的布局效果,可以彻底的屏蔽修改 density 所造成的所有未知和已知问题,但这样 AndroidAutoSize 也就无法对三方库进行适配

    说明:在使用主单位时,design_width_in_dp 和 design_height_in_dp 的单位必须是 dp,计算公式 dp = px / (DPI / 160) 将 px 尺寸转换为 dp 尺寸,如果实在找不到设备的 DPI 那就直接将 px 尺寸除以 3 或者 2 。

    3) 进阶使用 在 AndroidManifest.xml 中填写的设计尺寸,是整个项目的全局设计图尺寸,但是如果某些 Activity 页面由于某些原因,这个页面的设计图尺寸和在 AndroidManifest.xml 中填写的设计图尺寸不一样该怎么办呢?则可以让这个页面的 Activity 实现 CustomAdapt ,CustomAdapt 接口的第一个方法可以修改当前页面的设计尺寸。

    • 自定义 Activity
    public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt {
    
         /**
         * 是否按照宽度进行等比例适配 (为了保证在高宽比不同的屏幕上也能正常适配, 所以只能在宽度和高度之中选择一个作为基准进行适配)
         *
         * @return {@code true} 为按照宽度进行适配, {@code false} 为按照高度进行适配
         */
        @Override
        public boolean isBaseOnWidth() {
            return false;
        }
    
         /**
         * 设计图尺寸为 1080px * 1920px, 高换算成 dp 为 960 (1920px / 2 = 960dp)
         * 

    * 返回的设计尺寸, 单位 dp * {@link #getSizeInDp} 须配合 {@link #isBaseOnWidth()} 使用, 规则如下: * 如果 {@link #isBaseOnWidth()} 返回 {@code true}, {@link #getSizeInDp} 则应该返回设计图的总宽度 * 如果 {@link #isBaseOnWidth()} 返回 {@code false}, {@link #getSizeInDp} 则应该返回设计图的总高度 * 如果您不需要自定义设计图上的设计尺寸, 想继续使用在 AndroidManifest 中填写的设计图尺寸, {@link #getSizeInDp} 则返回 {@code 0} * * @return 单位 dp */ @Override public float getSizeInDp() { return 667; } }

    如果某个 Activity 想放弃适配,让这个 Activity 实现 CancelAdapt 接口即可。

    • 自定义 Fragment Fragment 的自定义方式和 Activity 是一样的,只不过在使用前需要先在 App 初始化时开启对 Fragment 的支持
    AutoSizeConfig.getInstance().setCustomFragment(true);
    
    • 实现 CustomAdapt
    public class CustomAdaptFragment extends Fragment implements CustomAdapt {
    
        @Override
        public boolean isBaseOnWidth() {
            return false;
        }
    
        @Override
        public float getSizeInDp() {
            return 667;
        }
    }
    

    4) 万能解决方案 在任何情况下本来适配正常的布局突然出现适配失效,适配异常等问题,只要重写 Activity 的 getResources() 方法即可,如果是 Dialog、PopupWindow 等控件出现适配失效或适配异常,同样在每次 show() 之前调用 AutoSize#autoConvertDensity() 即可。

    @Override
    public Resources getResources() {
        //需要升级到 v1.1.2 及以上版本才能使用 AutoSizeCompat
        AutoSizeCompat.autoConvertDensityOfGlobal((super.getResources());//如果没有自定义需求用这个方法
        AutoSizeCompat.autoConvertDensity((super.getResources(), 667, false);//如果有自定义需求就用这个方法
        return super.getResources();
    }
    
    推荐文章
    • 【今日头条屏幕适配方案终极版正式发布】
    • 一种非常好用的 Android 屏幕适配-- smallestWidth
关注
打赏
1658837700
查看更多评论
立即登录/注册

微信扫码登录

0.0446s