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 是和屏幕寬度是成正比的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章