android开发:自定义view不同设备尺寸适配技巧

1.首先抛出一个问题:
自定义中getWidth()、getHeight()、canvas.drawCircle()等方法获取的值和设置的值是dp值还是px

在这里插入图片描述
我百度了一下得到的答案是px

2.验证:

我自定义一个view,在ondraw()中绘制一个圆

package com.example;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @Author: david.lvfujiang
 * @Date: 2020/1/16
 * @Describe:
 */
public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        Log.e("TAG",canvas.getWidth()+","+ Resources.getSystem().getDisplayMetrics());
        canvas.drawCircle(200,200,200,paint);
    }
}

设备1:1440 x 2560 像素密度:560 density:3.5
在这里插入图片描述
设备2:1080 x 1920 像素密度:420 density:2.6
在这里插入图片描述
我们知道我们的圆占400像素
1080 x 1920的设备上显得比较大,宽度占比:400:1080 = 37%
1440 x 2560 的设备上则显得比较小,宽度占比:400:1080 = 27%
因此我们运行出来的效果在不同的手机屏幕可能有的大有的小,我们适配的最终希望是:我的圆无论在什么手机上显示的占比度都是一样的。

3根据density计算我们的view高宽度

package com.example;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * @Author: david.lvfujiang
 * @Date: 2020/1/16
 * @Describe:
 */
public class MyView extends View {
    public MyView(Context context) {
        super(context);
    }

    public MyView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public MyView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();
        Log.e("TAG",canvas.getWidth()+","+ Resources.getSystem().getDisplayMetrics());
        canvas.drawCircle(dp2pix(100),dp2pix(100),dp2pix(100),paint);
    }
    private int dp2pix(int dp) {
        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().getDisplayMetrics());
    }
}

在view中添加dp2pix()方法根据系统density计算圆的高宽
(设备1:1440 x 2560 像素密度:560 density:3.5) 计算得到的圆:直径*density = 700px 占屏幕宽度:48%.
(设备2:1080 x 1920 像素密度:420 density:2.6)计算得到的圆:直径*density = 520px 占屏幕宽度:48%
在这里插入图片描述在这里插入图片描述
我们知道我们计算px值的时候是需要density配合:
(设备1:1440 x 2560 像素密度:560 density:3.5) 计算得到的圆:700px 占屏幕宽度:48%
(设备2:1080 x 1920 像素密度:420 density:2.6)计算得到的圆:520px 占屏幕宽度:48%

设备1的density值比较大,所以我们计算得到圆的像素比较大,设备2的density值比较小,我们计算得到圆的像素比较小,而像素又是相对单位,因此在设备1和设备2上显示的大小正好一样。当然这是density值和设备宽度分辨率成正比的情况下,density是由系统决定不是由屏幕的分辨率决定。如果说设备1和设备2的像素密度正好反过来:
(设备1:1440 x 2560 像素密度:420 density:2.6)
(设备2:1080 x 1920 像素密度:560 density:3.5
那我计算圆的时候会得到:
(设备1:1440 x 2560 像素密度:420 density:2.6) 计算得到的圆:520px占屏幕宽度:36%
(设备2:1080 x 1920 像素密度:560 density:3.5)计算得到的圆:700px占屏幕宽度:64%

4.解决density带来的问题
为了解决该问题我们需要引入今日头条适配方案:
Android 屏幕适配之框架(AndroidAutoSize)(今日头条)适配

android开发:今日头条屏幕适配方案

AndroidAutoSize的核心是动态的修改系统的density值
假设我们把所有的屏幕宽度都看成360dp(总设计图纸的dp),通过dppx的转换率我们可以知道,设备1的density = 3,设备2的density = 4。那我们的圆在设备1上的尺寸则是600px,占屏幕宽度的55%,在设备2上尺寸是800px,占屏幕宽度的55%。使用AndroidAutoSize动态的修改density ,保证了我们的density 是和屏幕宽度是成正比的。

发布了194 篇原创文章 · 获赞 42 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/qq_39027256/article/details/103999737