王學崗高級UI8——————屏幕適配

1,屏幕分辨率限定符,已經過時了,不在介紹
2,smallestWidth 限定符
使用:(1)android studio中安裝ScreenMatch插件;
(2)點擊values文件夾下的任意文件,右擊,選中ScreenMatch。

在這裏插入圖片描述
生成如下文件
在這裏插入圖片描述
然後移動screenMatch_example_dimens文件到values文件夾下。並修改名字爲dimens
右擊dimens文件,然後會生成如下
在這裏插入圖片描述

二動態運行時的屏幕適配

package com.dn_alan.myapplication.pixel;

import android.content.Context;
import android.util.DisplayMetrics;
import android.view.WindowManager;

public class Utils {
    private static Utils utils;
    private Context mContext;
    //這裏是設計稿參考寬高,UI設計師按照這個寬高設計
    private static final float STANDARD_WIDTH = 1080;
    private static final float STANDARD_HEIGHT = 1920;
    //這裏是屏幕顯示寬高,當前屏幕的寬和高
    private int mDisplayWidth;
    private int mDisplayHeight;

    public Utils(Context context) {
        mContext = context;
        //獲取屏幕寬高
        if (mDisplayWidth == 0 || mDisplayHeight == 0) {
            WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            if (windowManager != null) {
                //寬高獲取
                DisplayMetrics displayMetrics = new DisplayMetrics();
                //如果不是NavigationBar沉浸式(不包含NavigationBar)
                windowManager.getDefaultDisplay().getMetrics(displayMetrics);
//                windowManager.getDefaultDisplay().getRealMetrics(displayMetrics);//真實屏幕寬高
                //判斷當前的橫豎屏
                if (displayMetrics.widthPixels > displayMetrics.heightPixels) {
                    //橫屏
                    mDisplayWidth = displayMetrics.heightPixels;
                    mDisplayHeight = displayMetrics.widthPixels - getStatusBarHeight(context);
                } else {
                    //豎屏
                    mDisplayWidth = displayMetrics.widthPixels;
                    mDisplayHeight = displayMetrics.heightPixels - getStatusBarHeight(context);
                }
            }
        }
    }

    public static Utils getInstance(Context context) {
        if (utils == null) {
            utils = new Utils(context);
        }
        return utils;
    }

    //獲取狀態欄高度
    public int getStatusBarHeight(Context context) {
        int resId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
        //大於0表示resID存在
        if (resId > 0) {
            return context.getResources().getDimensionPixelSize(resId);//獲取具體的像素值
        }
        return 0;
    }

    //獲取水平方向的縮放比例
    public float getHorizontalScale() {
        return mDisplayWidth / STANDARD_WIDTH;
    }

    //獲取垂直方向的縮放比例
    public float getVerticalScale() {
        return mDisplayHeight / (STANDARD_HEIGHT - getStatusBarHeight(mContext));
    }
}

我們重寫RelativeLayout佈局,重寫它的onMeasure();

package com.dn_alan.myapplication.pixel;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.widget.RelativeLayout;

public class ScreenAdapterLayout extends RelativeLayout {
    private boolean flag;

    public ScreenAdapterLayout(Context context) {
        super(context);
    }

    public ScreenAdapterLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ScreenAdapterLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        if (!flag) { //防止兩次測量,onMessasure()執行了兩次
            flag = true;
            //獲取橫豎方向等比
            float scaleX = Utils.getInstance(getContext()).getHorizontalScale();
            float scaleY = Utils.getInstance(getContext()).getVerticalScale();
            //子View個數
            int childCount = getChildCount();
            //遍歷所有的子View,改變所有的子View的寬和高
            for (int i = 0; i < childCount; i++) {
                View child = getChildAt(i);
                LayoutParams params = (LayoutParams) child.getLayoutParams();
                //當前子View的寬
                params.width = (int) (params.width * scaleX);
                params.height = (int) (params.height * scaleY);
                params.leftMargin = (int) (params.leftMargin * scaleX);
                params.rightMargin = (int) (params.rightMargin * scaleX);
                params.topMargin = (int) (params.topMargin * scaleY);
                params.bottomMargin = (int) (params.bottomMargin * scaleY);
                child.setPadding((int) (child.getPaddingLeft() * scaleX), (int) (child.getPaddingTop() * scaleY),
                        (int) (child.getPaddingRight() * scaleX), (int) (child.getPaddingBottom() * scaleY));
            }
        }
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}

在佈局中可以直接使用px爲單位

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
        android:id="@+id/textView"
        android:layout_width="1040px"
        android:layout_height="80px"
        android:layout_marginLeft="20px"
        android:layout_marginTop="10px"
        android:layout_marginRight="20px"
        android:background="#f00" />

    <TextView
        android:id="@+id/textView2"
        android:layout_width="680px"
        android:layout_height="680px"
        android:layout_marginLeft="200px"
        android:layout_marginTop="50px"
        android:layout_marginRight="200px"
        android:layout_below="@id/textView"
        android:background="#f00"/>

</RelativeLayout>

三密度適配(網上比較火的今日頭條適配就是密度適配)

package com.dn_alan.myapplication.density;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentCallbacks;
import android.content.res.Configuration;
import android.util.DisplayMetrics;

/**
 * 修改density,densityDpi值-直接更改系統內部對於目標尺寸而言的像素密度
 */
public class DensityUtils {
    private static final float WIDTH = 360;//參考像素密度(dp)
    private static float appDensity;//表示屏幕密度
    private static float appScaleDensity;//字體縮放比例,默認爲appDensity

    public static void setDensity(final Application application, Activity activity) {
        //獲取當前屏幕信息
        DisplayMetrics displayMetrics = application.getResources().getDisplayMetrics();
        if (appDensity == 0) {
            //初始化賦值
            appDensity = displayMetrics.density;
            appScaleDensity = displayMetrics.scaledDensity;
            //監聽字體變化
            application.registerComponentCallbacks(new ComponentCallbacks() {
                @Override
                public void onConfigurationChanged(Configuration newConfig) {
                    //字體發生更改,重新計算scaleDensity
                    if (newConfig != null && newConfig.fontScale > 0) {
                        appScaleDensity = application.getResources().getDisplayMetrics().scaledDensity;
                    }
                }

                @Override
                public void onLowMemory() {

                }
            });
        }
        //計算目標density scaledDensity
        //屏幕寬度:displayMetrics.widthPixels
        float targetDensity = displayMetrics.widthPixels / WIDTH;//1080/360=3;
        float targetScaleDensity = targetDensity * (appScaleDensity / appDensity);
        int targetDensityDpi = (int) (targetDensity * 160);
        //替換Activity的值
        //px = dp * (dpi / 160)
        DisplayMetrics dm = activity.getResources().getDisplayMetrics();
        dm.density = targetDensity;  //(dpi/160) 後得到的值
        dm.scaledDensity = targetScaleDensity;
        dm.densityDpi = targetDensityDpi;  //dpi
    }
}

package com.dn_alan.myapplication.density;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

import com.dn_alan.myapplication.R;

public class DensityActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
//        //設置density
        DensityUtils.setDensity(getApplication(), this);
        setContentView(R.layout.activity_density);
    }

}

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/tv1"
        android:layout_width="100dp"
        android:layout_height="40dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="10dp"
        android:layout_marginRight="20dp"
        android:background="#f00" />

    <TextView
        android:id="@+id/tv2"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_marginTop="50dp"
        android:layout_below="@id/tv1"
        android:background="#f00"/>

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