Android之设备像素、密度、适配

在Terminal中运行一下命令:

adb shell wm size 

或者

adb shell dumpsys window windows

可以获取所连接的设备分辨率。

获取屏幕的宽高像素和密度等工具类:

/**
 * 获取屏幕的宽高像素和密度等工具类
 */
 
public class DisplayUtil {
    private static final String TAG = "DisplayUtil";
 
    public static DisplayMetrics getDisplayMetrics(Activity activity){
        DisplayMetrics displayMetrics = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            //4.2开始有虚拟导航栏,增加了该方法才能准确获取屏幕高度
            activity.getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics);
        }else{
            activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
            //displayMetrics = activity.getResources().getDisplayMetrics();//或者该方法也行
        }
        return displayMetrics;
    }
 
    public static DisplayMetrics getDisplayMetrics(Context context){
        WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
            windowManager.getDefaultDisplay().getRealMetrics(displayMetrics);
        }else{
            windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        }
        return displayMetrics;
    }
 
    public static void printDisplayMetrics(Activity activity){
        DisplayMetrics displayMetrics = getDisplayMetrics(activity);
        Log.v(TAG,"---printDisplayMetrics---" +
                "widthPixels=" + displayMetrics.widthPixels
                + ", heightPixels=" + displayMetrics.heightPixels
                + ", density=" + displayMetrics.density
                + ", densityDpi="+displayMetrics.densityDpi);
    }
 
    public static void printDisplayMetrics(Context context){
        DisplayMetrics displayMetrics = getDisplayMetrics(context);
        Log.v(TAG,"---printDisplayMetrics---" +
                "widthPixels=" + displayMetrics.widthPixels
                + ", heightPixels=" + displayMetrics.heightPixels
                + ", density=" + displayMetrics.density
                + ", densityDpi="+displayMetrics.densityDpi);
    }
 
}

以上操作都是进行一些特殊机型的设备获取属性,单独进行特殊适配。

在此记录一些关于屏幕适配的常用概念:

概念

1、像素(px):

通常所说的像素,就是CCD/CMOS上光电感应元件的数量,一个感光元件经过感光,光电信号转换,A/D转换等步骤以后,在输出的照片上就形成一个点,我们如果把影像放大数倍,会发现这些连续色调其实是由许多色彩相近的小方点所组成,这些小方点就是构成影像的最小单位“像素”(Pixel)。

简而言之,像素就是手机屏幕的最小构成单元。


2、分辨率:

手机在横向、纵向上的像素点数总和,一般描述成 宽*高 ,即横向像素点个数*纵向像素点个数。


3、屏幕尺寸(in):

手机对角线的物理尺寸,单位 英寸(inch),一英寸大约2.54cm,常见的尺寸有4.7寸、5寸、5.5寸、6寸


4、屏幕像素密度(dpi):

每英寸长度上像素点个数。例如,每英寸内有160个像素点,则其像素密度为160dpi。

公式: 像素密度=像素/尺寸 (dpi=px/in)


5、标准屏幕像素密度(mdpi):

每英寸长度上还有160个像素点,即称为标准屏幕像素密度(mdpi)。


6、像素密度等级:

手机真实像素密度与标准屏幕像素密度(160dpi)的比值。官方给出的0.75、1、1.5、2、3、4,即对应120dpi、160dpi、240dpi、320dpi、480dpi、640dpi。


7、密度无关像素(dp):

density-independent pixel,叫dp或dip,与终端上的实际物理像素点无关。可以保证在不同屏幕像素密度的设备上显示相同的效果,是安卓特有的长度单位。


8、独立比例像素(sp):

scale-independent pixel,叫sp或sip,字体大小专用单位,可根据字体大小首选项进行缩放;

推荐使用12sp、14sp、18sp、22sp作为字体大小,不推荐使用奇数和小数,容易造成精度丢失,12sp以下字体太小。


9、尺寸、像素、像素密度关系:

这里写图片描述


10、px与dp关系:

像素 = dp * 像素密度等级,即 px = dp * (dpi / 160)

知道公式之后感觉自己可不得了了,以后知道设备尺寸和像素之后就可以进行计算。一顿操作之后,然而并没有什么用,公司的五六个安卓设备,只有一个小米pad符合这个公式。每个的设备的dpi都是厂家定义的,还得必须根据真实的设备进行操作。

smallestWidth 限定符屏幕适配方案:

原理:

开发者先在项目中根据主流屏幕的最小宽度 (smallestWidth) 生成一系列 values-sw<N>dp 文件夹 (含有 dimens.xml 文件),当把项目运行到设备上时,系统会根据当前设备屏幕的 最小宽度 (smallestWidth) 去匹配对应的 values-sw<N>dp 文件夹,而对应的 values-sw<N>dp 文件夹中的 dimens.xml 文字中的值,又是根据当前设备屏幕的 最小宽度 (smallestWidth) 而定制的,所以一定能适配当前设备。

如果系统根据当前设备屏幕的 最小宽度 (smallestWidth) 没找到对应的 values-sw<N>dp 文件夹,则会去寻找与之最小宽度 (smallestWidth) 相近的 values-sw<N>dp 文件夹,系统只会寻找小于或等于当前设备 最小宽度 (smallestWidth) 的 values-sw<N>dp,这就是优于宽高限定符屏幕适配方案的容错率,并且也可以少生成很多 values-sw<N>dp 文件夹,减轻 App 的体积。

公司就你一个安卓开发,整这些乱七八糟的事也很烦,做适配还是:今日头条的适配比较好用,主要是成本低,效率高。

今日头条适配方案:

好文章:今日头条屏幕适配方案终极版正式发布!,项目的Github地址

manifest中配置:指定设计图上的宽高

<manifest>
    <application>            
        <meta-data
            android:name="design_width_in_dp"
            android:value="360"/>
        <meta-data
            android:name="design_height_in_dp"
            android:value="640"/>           
     </application>           
</manifest>

页面使用此方案进行适配:

// Activity
public class CustomAdaptActivity extends AppCompatActivity implements CustomAdapt {

    @Override
    public boolean isBaseOnWidth() {
        return false;
    }

    @Override
    public float getSizeInDp() {
        return 667;
    }
}

// Fragment
public class CustomAdaptFragment extends Fragment implements CustomAdapt {

    @Override
    public boolean isBaseOnWidth() {
        return false;
    }

    @Override
    public float getSizeInDp() {
        return 667;
    }
}

特定页面不使用此方案:

// Activity
public class CancelAdaptActivity extends AppCompatActivity implements CancelAdapt {

}

// Fragment
public class CancelAdaptFragment extends Fragment implements CancelAdapt {

}

配置属性:选择任意单位:pt, in, mm,不进行dp转换。

AutoSizeConfig.getInstance().getUnitsManager()
        .setSupportDP(false)
        .setSupportSP(false)
        .setSupportSubunits(Subunits.MM);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值