天天看點

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

目錄:

  • 螢幕适配的方式都有哪些
    • 1 方式之-dp
      • 11 名詞解釋
      • 12 res檔案夾下的目錄分類
      • 13 Android中的像素密度分辨率dp和px的關系
      • 14布局裡的160dp和180dp的
    • 方式之-dimens尺寸
    • 方式之-layout
    • 方式之-代碼适配
    • 方式之-weight權重
      • 多個相對的标準權重
      • 單個相對父布局的權重
      • 自動權重
  • 二螢幕适配的處理技巧都有哪些
    • 橫豎屏的切換
    • 權重的反比例

1. 螢幕适配的方式都有哪些?

1.1 方式之-dp

1.1.1 名詞解釋:

  • 分辨率

    480*800,1280*720,表示像素點的總和

  • px(pix)-像素

    是螢幕裡的最小單元

  • dpi-像素密度
    • 每英寸螢幕具有的像素數量,像素密度越大,細節越豐富
    • 公式:像素密度 = √{(長度像素數^2+寬度像素數^2)}/ 螢幕尺寸
    • 尺寸機關為:英寸;螢幕尺寸為:對角線長度(如下圖)
      "Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

1.1.2 res檔案夾下的目錄分類

(如圖)

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

應用查找圖檔的順序:

先從自己開始(沒有)->逐個就往高的找(沒有)->就往比自己低的找

1.1.3 Android中的像素密度/分辨率/dp和px的關系

類型 dip 分辨率 dp和px比例
ldip 120 240*320 1dp = 0.75px
mdip(标準) 160 320*480 1dp = 1px
hdip 240 480*800 1dp = 1.75px
xhdip 320 720*1280 1dp = 2px
xxhdip 480 1080*1920 1dp = 3px

比例圖如下:

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?
  • 由上面的标準mdip,那麼如果在320*480的手機上,隻需要dp就等效于px,因為1:1
  • 我們在代碼運算過程中經常要做dp和px的互換,根據上面的比例特點.我們隻需通過擷取資源.擷取螢幕分辨率.擷取比例即可
/*
       density   分辨率       dp和px的轉換
ldip    120     240*320     1dp = 0.75px
mdip    160     320*480     1dp = 1px
hdip    240     480*800     1dp = 1.5px
xhdip   320     720*1280    1dp = 2px
xxhdip  480     1080*1920   1dp = 3px

px和dip的轉換,隻需擷取比例值即可;得出dp和px
參考标準的mhdip,額算出其他:pixels=dips*(density/160)
如果是240*320的求得density肯定是1;
1.擷取比例值-自動根據目前的手機擷取比例值
(不同分辨率得到的不同,比如我的模拟器720*1280傳回2)
(PS:傳入dp得px:乘以比例即可;傳入px得dp:除以比例即可),寫成工具類
2.四舍五入

*/
public class DensityUtil {  

    /** 
     * 根據手機的分辨率從 dip 的機關 轉成為 px(像素) 
     */  
    public static int dip2px(Context context, float dpValue) { 

        final float scale = context.getResources().getDisplayMetrics().density;    
        return (int) (dpValue * scale + f);  
    }  

    /** 
     * 根據手機的分辨率從 px(像素) 的機關 轉成為 dp 
     */  
    public static int px2dip(Context context, float pxValue) {  

        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue / scale + f);  
    }  
}  
           

1.1.4布局裡的160dp和180dp的

160dp:

  • 設定一個按鈕的寬度為160dp,在320*480分辨率的機器裡,那麼正好是一半(因為1:1)
  • 在240*320的機器裡,正好也顯示一半,因為(1:0.75),160dp = 120px
  • 在480*800的機器裡,也是一半,因為(1:1.5).160dp = 240px
  • 是以在以上三種分辨率下設定多少dp是等效的,歸為一檔.
<Button
        android:background="#ff0000"
        android:layout_width="60dp"
        android:layout_height="wrap_content"/>
    <Button
        android:background="#00ff00"
        android:layout_width="100dp"
        android:layout_height="wrap_content"/>
           

三種分辨率同樣的代碼都顯示這樣的效果:

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

180dp:

  • 如果将上面的160dp,放到720*1280或者1920 *1080,那麼得到的效果和以上機器是不同的
  • 設定180dp寬度的按鈕,在這兩者裡面的效果是一樣的
  • 因為:720*1280(比例是:1:2)是以180dp = 360px,就是一半
  • 1920*1080(比例是:1:3)是以180dp = 540px,也是一半
  • 是以這兩種分辨率下設定的dp是等效的,也是一檔
<Button
        android:background="#ff0000"
        android:layout_width="80dp"
        android:layout_height="wrap_content"/>
    <Button
        android:background="#00ff00"
        android:layout_width="100dp"
        android:layout_height="wrap_content"/>
           

兩種分辨率下都顯示同樣效果

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

2.方式之-dimens(尺寸)

  • (PS:根據上一節的160dp和180dp的講解,我們現在通過自動dimens解決自動适配問題)
  • 1.在res目錄下有預設的values檔案夾和dimens.xml檔案
  • 2.為了自動适配1280 *720和1920 *1080分辨率,我們分邊建立各自的檔案夾
    • values-1280x720(eclipase寫法),Android Studio寫成values-w320dp
      "Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?
  • 3.把剛才的dimens.xml複制一份到目标檔案夾
    • 預設的dimens.xml寫成160dp,移到新檔案的定義成180dp;
      "Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?
  • 4.最後在布局檔案中寫機關大小時,用@dimens/width即可,自動根據螢幕靈活調用
    "Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?
    (PS:因為有預設的和指定各種分辨率(另外寫1920*1080的,雖然和720等效,但是還是要寫,否則他就用預設的了)的檔案夾,是以找不到指定的就用預設的)

3.方式之-layout

  • 原理和上述情況一樣,些不同的layout,會根據分辨率自動找到合适的layout
    "Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

4.方式之-代碼适配

  • 需求:通過代碼設定,讓一個TextView的寬和高都為螢幕的一半;
  • 初始:布局是預設的包裹,如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">
    <!-- 現在是預設的包裹 -->
    <TextView
        android:id="@+id/tv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#e18080"
        android:text="hello_world"/>
</RelativeLayout>
           
"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

* 步驟:

* 1.擷取tv控件

* 2.擷取目前機器的分辨率.

* 3.建立一個和跟布局一樣(根是線性就線性,是關系就設定關系)的參數,構造傳入長和寬(分辨率的一半)

* 4.再讓tv控件設定參數即可.

*代碼如下:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.
        TextView tv = (TextView) findViewById(R.id.tv);
        //2.
        int height = getWindowManager().getDefaultDisplay().getHeight();
        int width = getWindowManager().getDefaultDisplay().getWidth();
        //3.
        RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams((int) ((float)width/+), (int) ((float)height/+));
        //4.
        tv.setLayoutParams(params);
    }
}
           

效果:

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

5.方式之-weight權重

(PS:必須是線性布局)

1.多個相對的标準權重

  • 如果是橫向:把高度設定為0dp
  • 如果是豎向:把寬度設定為0dp
  • 然後色字不同控件所占的權重
<Button
        android:layout_weight="1"
        android:text="bt1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"/>
    <Button
        android:text="bt2"
        android:layout_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"/>
 </LinearLayout>
           

效果:

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

2.單個相對父布局的權重

  • 1.設定父布局的總權重:SumWeight
  • 2.設定自己的所占的權重即可
<LinearLayout
    android:weightSum="3"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <Button
        android:layout_weight="2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="bt1"/>
</LinearLayout>
           

效果:

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

3.自動權重

  • 想讓前面的完全填充,并且設定權重
  • 然後後面的用包裹即可
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <EditText
        android:text="請輸入内容"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="輸出"/>
</LinearLayout>
           

效果如下:

"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?

二.螢幕适配的處理技巧都有哪些?

橫豎屏的切換

(正常情況下,每次橫豎屏切換都會導緻Activity的重新建立)

  • 1.在活動銷毀前儲存活動狀态(重寫onSaveInstanceState方法),可以參考前面我們講的思維(點選通路).
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //切換螢幕後擷取資訊
    if (savedInstanceState != null) {
        System.out.println(savedInstanceState.get("height")+"-------");
        System.out.println(savedInstanceState.get("width")+"-------");
    }
}
    //儲存資訊
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putInt("height", );
        outState.putInt("width", );
        super.onSaveInstanceState(outState);
    }
           
  • 2.在清單檔案把方向寫死:
    • android:screenOrientation=”portrait”(landscape是橫向,portrait是縱向)
  • 3.如果不想重新讓Activity調用,就設定配置更改
    • 在清單檔案設定三個參數:
      • 方向|按鍵隐藏|螢幕尺寸
        android:configChanges="orientation|keyboardHidden|screenSize"
                   
    • 另外重寫Activity裡的更改方法
      • 如果切換橫豎屏,之後重新調用這個方法
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        //橫向就幹嘛 TODO
    } 
    else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
        //豎向就幹嘛 TODO
    }
}
           

權重的反比例

經過改善一般我們都是設定0dp,然後使用權重,占多少就占用多少部分

如果反比例,比如按鈕A權重是1,按鈕B是2,那麼就反過來了,代碼和效果圖如下.

就是不用0dp,而改用填充

<Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="bt1"/>

        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:text="bt2"/>
    </LinearLayout>
           
"Android 螢幕适配"-Android面試必問"精華技能點"彙總1. 螢幕适配的方式都有哪些?二.螢幕适配的處理技巧都有哪些?