ANDROID高级UI-屏幕适配终极解决方案

众人周知,移动开发分为android和ios,android由于系统是开源,引来大量厂商,在市场上华为,小米,opper,vivo,等等各大手机厂商,由于手机多姿多彩,就引起众人头疼的事,就是屏幕适配问题,在本人以往开发经验,华为适配极其很难适配,有的布局明明在模拟器或者真机运行效果差不多,但是在个别手机就有点极为变态,为了在开发过程中避免这种问题,本人也是在不断的学习,和研究来达到在开发过程中考虑到适配的问题,就写下这篇文章,希望各位捧场。

屏幕适配分为:

  • 百分比布局适配
  • 动态运行适配

屏幕适配常见的方式:

  1. 避免写死控件尺寸,使用wrap_content, match_parent
  2. LinearLayout xxx:weight="0.5“
  3. RelativeLayout xxx:layout_centerInParent=“true” …
  4. ContraintLayout xxx:layout_constraintLeft_toLeftOf=“parent”…
  5. Percent-support-lib xxx:layout_widthPercent=“30%” …

图片资源适配

  1. .9图或者SVG图实现缩放
  2. 备用位图匹配不同分辨率

首先要达到屏幕适配,就先要了解屏幕的有关信息

  • 屏幕尺寸

屏幕尺寸一般是屏幕对角线长度,单位是英寸,比如4.7寸,5.7寸
ANDROID高级UI-屏幕适配终极解决方案_第1张图片

  • 屏幕分辨率

如 1920×1080,是指在手机屏幕的像素点的个数,单位是px,1px = 1 像素点,一般是纵向像素 × 横向像素,意味着高有 1920
个像素点,宽有 1080 个像素点。
ANDROID高级UI-屏幕适配终极解决方案_第2张图片

  • 屏幕像素密度

指每英寸上的像素点数,单位是 dpi 像素密度和屏幕尺寸和屏幕分辨率有关,它是由对角线的像素点数除以屏幕的大小得到的关系如下:
ANDROID高级UI-屏幕适配终极解决方案_第3张图片

dp、dip、dpi、sp、px

  1. dp:是Android 特有的,意为密度无关像素,Google 发布的 BASELINE(基准线)为 160,以此为基准。
  2. dip:Density Independent Pixels,同dp一个意思,目前废弃了,一般都写dp。 dpi:即为屏幕像素密度的单位
  3. sp:Scale-IndependentPixels的缩写,可以根据文字大小首选项自动进行缩放。Google推荐我们使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,为避免精度损失,建议最好不要使用奇数和小数。
  4. px:就是我们常说的像素

mdpi、hdpi、xhdpi、xxhdpi、xxxhdpi
ANDROID高级UI-屏幕适配终极解决方案_第4张图片ANDROID高级UI-屏幕适配终极解决方案_第5张图片
有了基本概念,下来就讲讲关于适配的话题。

屏幕适配

  • 屏幕分辨率限定符(不推荐)

屏幕分辨率限定符适配需要在 res 文件夹下创建各种屏幕分辨率对应的 values-xxx 文件夹,如下图

ANDROID高级UI-屏幕适配终极解决方案_第6张图片

然后根据一个基准分辨率,例如基准分辨率为 1280x720,将宽度分成 720 份,取值为 1px~720px,将高度分成 1280
份,取值为 1px~1280px,生成各种分辨率对应的 dimens.xml 文件。如下分别为分辨率 1280x720 与1920x1080 所对应的横向dimens.xml 文件:

ANDROID高级UI-屏幕适配终极解决方案_第7张图片

假设设计图上的一个控件的宽度为 720px,
那么布局中就写android:layout_width="@dimen/x720"
,当运行程序的时候,系统会根据设备的分辨率去寻找对应的 dimens.xml 文件。
例如运行在分辨率为 1280x720 的设备上,系统会自动找到对应的 values-1280x720 文件夹下的 lay_x.xml 文件
由上图可知
x720 对应的值为720.px,可铺满该屏幕宽度。运行在分辨率为 1920x1080 的设备上,系统会自动找到对应的 values-1920x1080 文件夹下的 lay_x.xml 文件,
由上图可知
x720 对应的值为 1080.0px,可铺满该屏幕宽度。这样就达到了屏幕适配的要求!

  • 动态运行时适配

动态适配大概逻辑思维就是:
参照UI设计师提供的设计稿的比例为参考。
然后获取到屏幕的宽高减去状态栏的高度得到实际的宽高,算出宽高的比例,然后在系统绘画的时候拿出每个子View进行缩放。

  1. 首先需要获取屏幕的宽高和设计稿的尺寸大小:
//这里是设计稿参考宽高
private static final float STANDARD_WIDTH = 1080;
private static final float STANDARD_HEIGHT = 1920;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null) {
    //宽高获取
    DisplayMetrics displayMetrics = new DisplayMetrics();
    //如果不是NavigationBar沉浸式(不包含NavigationBar)
    windowManager.getDefaultDisplay().getMetrics(displayMetrics);
  1. 获取状态栏的高度
//获取状态栏高度
public int getStatusBarHeight(Context context) {
    int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resId > 0) {
        return context.getResources().getDimensionPixelSize(resId);//获取具体的像素值
    }
    return 0;
}
  1. 为了考虑周全,一般正常情况下是竖屏,但是也有横屏,那么也许去处理,判断是竖屏还是横屏:
 if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
        //横屏
        mDisplayWidth = displayMetrics.heightPixels;
        mDisplayHeight = displayMetrics.widthPixels - getStatusBarHeight(context);
    } else {
        //竖屏
        mDisplayWidth = displayMetrics.widthPixels;
        mDisplayHeight = displayMetrics.heightPixels - getStatusBarHeight(context);
    }
}

4:最后算出适配的比例:

//获取水平方向的缩放比例
public float getHorizontalScale() {
    return mDisplayWidth / STANDARD_WIDTH;
}

//获取垂直方向的缩放比例
public float getVerticalScale() {
    return mDisplayHeight / (STANDARD_HEIGHT - getStatusBarHeight(mContext));
}

5:循环拿出每个字View进行等比缩放:

//子View个数
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
    View child = getChildAt(i);

进行每个字view同等比缩放

LayoutParams params = (LayoutParams) child.getLayoutParams();
params.width = (int) (params.width * scaleX);
params.height = (int) (params.height * scaleY);
params.leftMargin = (int) (params.leftMargin * scaleX);
params.rightMargin = (int) (params.rightMargin * scaleX);
params.topMargin = (int) (params.topMargin * scaleY);
params.bottomMargin = (int) (params.bottomMargin * scaleY);
child.setPadding((int) (child.getPaddingLeft() * scaleX), (int) (child.getPaddingTop() * scaleY),
        (int) (child.getPaddingRight() * scaleX), (int) (child.getPaddingBottom() * scaleY));

效果:
ANDROID高级UI-屏幕适配终极解决方案_第8张图片
下载地址:
动态运行适配参考资料

最后建议

一般情况下采用普通适配方式就好,在万不得已的情况下,再去使用三方。

屏幕适配常见方式

1、避免写死控件尺寸,使用wrap_content, match_parent
2、LinearLayout xxx:weight="0.5“
3、RelativeLayout xxx:layout_centerInParent=“true” …
4、ContraintLayout xxx:layout_constraintLeft_toLeftOf=“parent”…
5、Percent-support-lib xxx:layout_widthPercent=“30%” …

ANDROID高级UI-屏幕适配终极解决方案_第9张图片

你可能感兴趣的:(ANDROID高级-UI动画,安卓适配,安卓动态适配,安卓比例适配)