android 螢幕適配一:通過自定義View的方式實現適配
實現原理:以一個特定的寬度尺寸的裝置為參考,在View載入的過程中,根據當前裝置的實際畫素換算出目標畫素,再作用到控制元件上。
通常UI給我們的設計稿只有一種畫素的標準,例如720 * 1280。 例如在設計稿上有一個控制元件寬度為螢幕尺寸的一半,即360px,假設我們真機的螢幕尺寸為1080 * 1920畫素,我們再佈局中設定控制元件尺寸也為360px,則顯示為螢幕的三分之一。但是我們想要效果仍然是顯示螢幕的一半。即寬度應該設定為540px,這裡的540px是如何得到的呢,這就是通過真實螢幕尺寸與參考設計稿的尺寸比例來得到的,即:(1080/720)*360 = 540。
下面通過程式碼來實現這一功能:
public class Utils { private static Utils utils; //這是設計稿參考的寬高 private static final float STANDARD_WIDTH = 720; private static final float STANDARD_HEIGHT = 1080; //這裡是螢幕的顯示寬高 private int mDisPlayWidth; private int mDisPlayHeight; public static Utils getInstance(Context context) { if (utils == null) { utils = new Utils(context.getApplicationContext()); //獲取application的context是防止記憶體洩漏 } return utils; } private Utils(Context context) { //獲取螢幕的寬高 if (mDisPlayHeight == 0 || mDisPlayWidth == 0) { //寬高還未賦值 WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); if (manager != null) { DisplayMetrics displayMetrics = new DisplayMetrics(); manager.getDefaultDisplay().getMetrics(displayMetrics); //此時displayMetrics就可以獲取到螢幕寬高資訊了 if (displayMetrics.widthPixels > displayMetrics.heightPixels) { //橫屏 mDisPlayWidth = displayMetrics.heightPixels; mDisPlayHeight = displayMetrics.widthPixels - getStatusBarHeight(context); } else { //豎屏 mDisPlayWidth = displayMetrics.widthPixels; mDisPlayHeight = displayMetrics.heightPixels - getStatusBarHeight(context); } } } } //獲取狀態列高度 public int getStatusBarHeight(Context context) { int resID = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); if (resID > 0) { //可以獲取到狀態列高度 return context.getResources().getDimensionPixelSize(resID); } return 0; } //獲取水平方向的縮放比例 public float getHorizontalScale() { return mDisPlayWidth / STANDARD_WIDTH; } //獲取垂直方向的縮放比例 public float getVerticalScale() { return mDisPlayHeight / STANDARD_HEIGHT; } } 複製程式碼
Utils工具類用來計算設計稿螢幕解析度和真實螢幕解析度的比例。
下面以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) { //防止比例的計算多次呼叫 float scaleX = Utils.getInstance(getContext()).getHorizontalScale(); float scaleY = Utils.getInstance(getContext()).getVerticalScale(); int count = getChildCount(); for (int i = 0; i < count; i++) { View child = getChildAt(i); LayoutParams params = (LayoutParams) child.getLayoutParams(); 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.leftMargin * scaleY); params.bottomMargin = (int) (params.leftMargin * scaleY); } flag = true; } super.onMeasure(widthMeasureSpec, heightMeasureSpec); } } 複製程式碼
下面在資源佈局中使用ScreenAdapterLayout。

這裡我設定的寬度為360px,我手機的畫素為1080*2248,但是顯示的view的寬度仍然為螢幕的一半。這是因為根據Utils把view的寬高做了換算。我們不需要關注真實螢幕的解析度。只需要根據設計稿的解析度來設定view的寬高。

注:博主菜雞一個,第一次寫部落格,希望得到大佬的指點。輕點噴o(╥﹏╥)o