美文网首页
Android 屏幕适配

Android 屏幕适配

作者: 浮世绘町 | 来源:发表于2020-07-14 11:34 被阅读0次

Android机型各种各样,在适配的过程中不仅要考虑分辨率、长宽比、还要考虑屏幕密度,尤其是屏幕密度会导致不同手机上的显示效果不同,有一种比较好的适配方式,在适配中通过density换算可以实现在所有所有手机上宽度都视为360dp,高度则按宽度的放大缩小比例去放大和缩小,这是竖屏的情况,横屏则可以将高度视为720dp,宽度则一样去按高度的比例去缩放,这样带来的好处就是控件,图片按相同比例缩放,不会变形,同时忽略了屏幕密度的影响,让控件和整个屏幕的相对比例和相对位置可以很好地适配。

实现原理和概念参考:https://www.jianshu.com/p/55e0fca23b4f

光讲可能没有感觉,放出实际效果看看:

图一:是开发时预览图


image.png

图2:是没做什么适配,dp的自适应结果,如果要达到与设计相同的结果是可以采取一些其他的适配方法,比如说按线性布局的比例去布局,按照约束布局固定于边界距离等,也是有很多方法,不过我用过的方法相对来说比较麻烦,而且有事会过度重绘导致界面性能较低。


image.png
图三:是使用该适配方案
image.png

可以看出这种方法已经能达到很好的适配效果,相对来说比较简单,代码量很少,不过在保证宽度适配的同时,由于手机的长宽比不同,所以高度不会完全适配。这也是可以通过一些方法解决的,要根据实际布局去做。

我把这个方法封装了一个工具类,根据传参不同是适配横屏和竖屏,可以直接用,

DensityUtil类:
package com.example.administrator.densitytest;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentCallbacks;
import android.content.res.Configuration;
import android.util.DisplayMetrics;

public class DensityUtil {

private static float sNoncompatDensity;
private static float sNoncompatScaledDensity;

public static void setCustomDensity(Activity activity, final Application application, int direction){//direction:0-竖屏,1-横屏
    final DisplayMetrics appDisplayMetrics = application.getResources().getDisplayMetrics();

    if(sNoncompatDensity == 0){
        sNoncompatDensity = appDisplayMetrics.density;
        sNoncompatScaledDensity = appDisplayMetrics.scaledDensity;
        application.registerComponentCallbacks(new ComponentCallbacks() {
            @Override
            public void onConfigurationChanged(Configuration newConfig) {
                if(newConfig != null && newConfig.fontScale >0 ){
                    sNoncompatScaledDensity = application.getResources().getDisplayMetrics().scaledDensity;
                }
            }

            @Override
            public void onLowMemory() {

            }
        });
    }

    float targetDensity = appDisplayMetrics.widthPixels/360;
    if(direction==1){//横屏
        targetDensity = appDisplayMetrics.widthPixels/640;
    }

// final float targetDensity = appDisplayMetrics.widthPixels/360;
// final float targetDensity = appDisplayMetrics.widthPixels/640;
final int targetDensityDpi = (int)(160*targetDensity);
final float targetScaledDensity = targetDensity * (sNoncompatScaledDensity/sNoncompatDensity);

    appDisplayMetrics.density = appDisplayMetrics.scaledDensity = targetDensity;
    appDisplayMetrics.densityDpi = targetDensityDpi;
    appDisplayMetrics.scaledDensity = targetScaledDensity;

    final DisplayMetrics activityDisplayMetrics = activity.getResources().getDisplayMetrics();
    activityDisplayMetrics.density = activityDisplayMetrics.scaledDensity = targetDensity;
    activityDisplayMetrics.densityDpi = targetDensityDpi;
    activityDisplayMetrics.scaledDensity = targetScaledDensity;
}

}
MainActivity:
package com.example.administrator.densitytest;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    DensityUtil.setCustomDensity(this,getApplication(),0);
    setContentView(R.layout.activity_main);
}

}
Demo地址:https://github.com/han103070/DensityTest

相关文章

网友评论

      本文标题:Android 屏幕适配

      本文链接:https://www.haomeiwen.com/subject/yeuxhktx.html