1. 程式人生 > >android 手機適配之values適配dimen值

android 手機適配之values適配dimen值

android 適配螢幕的方式有很多,最方便最直接的無非就是適配values裡的dimens檔案值來進行適配.
張鴻洋大神已經寫過一篇適配的文章,很詳細
但是我在閱讀的時候還是有點疑問,這個values-1920x1080到底是dp值還是手機解析度,因為我在實際操作中發現這樣一句話.
這裡寫圖片描述

很明顯可以看到在我寫的1920 * 1080上方有一句話 Screen dimension in dp ,是不是很奇怪,這裡讓我們寫dp值,我就納悶了,怎麼寫?我在網上找了一天,都沒有人解釋過.所以,我自己來做實驗驗證一下.我用的手機是三星note3 解析度 1920 * 1080

DisplayMetrics metric = new
DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 螢幕寬度(畫素) int height = metric.heightPixels; // 螢幕高度(畫素) float density = metric.density; // 螢幕密度(0.75 / 1.0 / 1.5) int densityDpi = metric.densityDpi; // 螢幕密度DPI(120 / 160 / 240)

通過上面程式碼取值 分別為 高度 1920 寬度 1080 螢幕密度 3 螢幕密度dpi 360

我生成了以下的檔案包
這裡寫圖片描述

可以看到差不多每種格式的value適配我都生成了一個,裡面放的dimens檔案

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <dimen name="dp_10">50dp</dimen>
</resources>

每個包下的檔案的後面的值都不一樣,有的是50 dp 有的是 100dp 等等
我按手機解析度生成了一個values-1920x1080的包 ,然後根據計算 px = dp*(dpi/160) 可以知道 三星note3的手機的sw是360dp sw是smallest screen width 的縮寫.生成values方式可參照第一張圖片.裡面有很多方式和種類.px 是1080 寬度 dpi 檢視可知是480 所以dp = 1080/3 = 360dp.

package com.example.administrator.myapplication;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.DisplayMetrics;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    private float getDp(int id){
        float dimen = 0;
        String string = this.getResources().getString(id).replace("dip", "");
        dimen = Float.parseFloat(string);
        return dimen;
    }

    public void left(View v ){
        float dp = getDp(R.dimen.dp_10);
        Toast.makeText(this,"dp="+dp,Toast.LENGTH_LONG).show();
    }

    public void right(View view){
        DisplayMetrics metric = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(metric);
        int width = metric.widthPixels; // 螢幕寬度(畫素)
        int height = metric.heightPixels; // 螢幕高度(畫素)
        float density = metric.density; // 螢幕密度(0.75 / 1.0 / 1.5)
        int densityDpi = metric.densityDpi; // 螢幕密度DPI(120 / 160 / 240)


        System.out.println("width=" + width + "height="+height+"dendity="+density+"densitydpi="+densityDpi);
        Toast.makeText(this,"width=" + width + "height="+height+"dendity="+density+"densitydpi="+densityDpi,Toast.LENGTH_LONG).show();

    }
}

兩個按鈕,分別加上點選事件left right .left 點選事件主要是取出手機適配到的dimens值並吐司,right檢視手機的資訊.

當我執行程式,點選按鈕,彈出的數值是values-sw360dp 包下的dimens檔案裡的值.因為手機的最小寬度經過換算正好是360dp 當手機的寬度>= 360dp 是就會選擇這個包下的.它只會選若螢幕寬度達到sw480 dp 則會選擇這個包下的. 我們進一步實驗,我刪除sw360dp的包,繼續執行程式,發現吐司出的數值是values-sw320dp包下的dimens裡的值,說明這個選擇是向下的,並且sw的等級很高.先匹配這個選項.xxxhdpi 和 values-1920x1080裡的檔案都沒有被選擇.
我繼續刪除values-sw320dp包 執行程式,發現吐司的數值為xxxhdpi下的dimens裡的數值,再刪除xxxhdpi 包, 執行,這時列印的是values-1920x1080 包下dimens裡的值,這也進一步說明 了這個1920x1080就是解析度而並非 screen dimension in dp ,不知道是不是谷歌的失誤.造成了一個誤區.這裡大家記住,這個就是解析度就對了,不是dp值.
繼續刪除values-1920x1080 這個包.執行,.吐司出的值是values-1024x600 裡的dimens的數值.說明這種匹配也是向下匹配的.

好了 ,現在已經很清晰了.還有一點要說,values-sw xx dp 這種格式是3.2 版本引入的 values xxxx*xxxx 解析度的樣式好像還要晚一點,如果有版本適配的需要注意不能用,否則系統不識別這個,還是用values-w xxx dp 這種.不過這種方式取值,在螢幕進行翻轉後會發生變化,而sw 的不會.要注意.

如果有不當之處歡迎指出,大家一起學習.