在作一個有關蘇果APP的項目中,可是fuck的是,我徹底使用相對佈局以後及線性佈局以後發現坑爹的事情了,屏幕不能適配,這是多大的痛,意味着,必須使用相應的代碼實現動態佈局!呵呵,不作項目不知道,只有真正地下手去作某些事情的時候,纔會發覺各類問題,本來打算先寫view與framgent實現tabhost功能的博客的,可是碰到了這個棘手問題必須先把他解決了!同時不知道各位網友有什麼好的方法來適配全部的安卓手機屏幕android
其實解決之道有不少,我選用的是使用代碼計算等比例高寬,讓其在相應的屏幕上顯示相應的比例高度就能夠了!固然網上有不少都是給的建議,卻沒有實實在在解決問題的博客!(但願集思廣益,可以獲得一個適合所有屏幕類型的架包,方便全部的安卓開發人員)工具
網上的建議,我進行了概括:佈局
通常狀況下的普通屏幕:ldpi是120,mdpi是160,hdpi是240,xhdpi是320。字體
須要根據物理尺寸的大小準備5套佈局,layout(放一些通用佈局xml文件,好比界面中頂部和底部的佈局,不會隨着屏幕大小變化,相似windos窗口的title bar),layout-small(屏幕尺寸小於3英寸左右的佈局),layout-normal(屏幕尺寸小於4.5英寸左右),layout-large(4英寸-7英寸之間),layout-xlarge(7-10英寸之間)this
須要根據dpi值準備5套圖片資源,drawable,drawalbe-ldpi,drawable-mdpi,drawable-hdpi,drawable-xhdpi設計
Android有個自動匹配機制去選擇對應的佈局和圖片資源code
DisplayMetrics metrics = new DisplayMetrics(); Display display = activity.getWindowManager().getDefaultDisplay(); display.getMetrics(metrics);//這裏獲得的像素值是設備獨立像素dp //DisplayMetrics metrics=activity.getResources().getDisplayMetrics(); 這樣得到的參數信息不正確,不要使用這種方式。
不能使用android.content.res.Resources.getSystem().getDisplayMetrics()。這個獲得的寬和高是空的。orm
設計圖先定下一個要設計的尺寸,並且儘可能採用在目前最流行的屏幕尺寸(好比目前佔屏幕比重比較多的是480系列,也便是480x800或者400x854,下面的圖標製做也在次基礎上進行比例的換算)上設計。
先了解一下屏幕的級別:xml
說明:htm
屏幕級別:
注意屏幕級別是按照密度分級,和像素沒有關係。若是非要讓密度和像素扯上關係,則須要一個參照系,android使用mdpi級別做爲標準參照屏幕,也就是說在320x480分辨率的手機上一個密度能夠容納一個像素。而後其餘密度級別則在此基礎上進行對比。若是理想狀況下,480x800的屏幕一個密度能夠容納1.5個像素。
物理大小:
單位是英寸而不是像素,也就說一個英寸在任何分辨率下顯示的大小都是同樣的,可是像素在密度不一樣的手機裏面顯示的實際的大小是不同的(這就是爲何android手機須要適配的緣由)。
而後就是重點。
假設1像素在160密度下顯示1英寸,則1像素在240密度基礎上顯示大約0.67英寸,在320密度下顯示0.5英寸。因而就出現一種狀況,在電腦上的一個像素,在不一樣的手機上看實際的大小不同。那麼怎麼讓「設計效果」在不一樣的手機上看起來顯示的區域同樣呢?
仍是假設一個像素在160密度下的顯示在一個密度內,也假設就是一英寸。那麼須要幾個像素才能在240密度級別下顯示在一英寸範圍內呢?答案是1.5個像素(根據上圖的比率換算)。
瞭解了這個關係,接下來就是圖標的製做。
關於切圖有幾個建議:
而後接下來的一切就和設計稿沒什麼關係。在切好圖的基礎上,根據屏幕密度、像素和實際大小的比例關係。假如設計司在480x800的分辨率下作好了設計圖,而且切好圖,若是你須要適配720x1280屏幕,該怎麼作?根據比例,他們的關係是2:3,因而你須要按照1.5倍比例製做圖標,好比你在480x800的設計稿上切下來一個20*20像素的圖,那麼你就須要製做一個等比放大成30x30像素的圖標,這樣同一個圖標在480x800的屏幕和720x1280的屏幕上顯示的實際大小才同樣。同理,若是你須要適配xxhdpi則須要在20x20的基礎上製做一個等比放大成40x40像素的圖標。
480*800切下來的圖咱們放在drawable-hdpi目錄下,按照2:3放大的圖標放在drawable-xhdpi目錄下,按照2倍放大的圖標放在drawable-xxhdpi目錄下。
android會根據手機的密度優先查找對應的目錄的資源,
好比408800分辨率下的手機若是密度是160,則自動加載drawable-hdpi這個目錄下的圖標,
若是7201280密度是240的手機自動加載drawable-xhdpi這個目錄下的圖標。若是沒有這個文件夾,則查找和240最接近的對應密度文件夾。
我我的獲得的啓示就是我在設計過程當中儘可能使控件不是使用數值,也就是說我在xml文件所使用的基本都是layout_weight\android:gravity="center"等,若是迫不得得以使用的話,就先寫着,而後經過相應的代碼來適配動態佈局
目前我所使用的方法呢就是本身寫個類,將view傳進去進行適配,同時注意了個人方案是能夠更改你原來所假設的屏幕寬度,而後一次性地進行適配!
package com.samuel.demosuguo; import android.content.Context; import android.util.DisplayMetrics; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RelativeLayout; /** * Created by samuelwnb on 2015/3/14. */ public class Autosize { int screenwidth = 640;//默認屏幕寬度爲640 /*** * 獲得默認屏幕寬度 * @return */ public int getScreenwidth() { return screenwidth; } /*** * 更改默認屏幕寬度 * @param screenwidth */ public void setScreenwidth(int screenwidth) { this.screenwidth = screenwidth; } //實際屏幕大小 static int screensize = 0; public static void setScreensize(int screensize) { Autosize.screensize = screensize; } /** * 獲取屏幕的大小 * @param context//爲activity * @return 實際屏幕的打下 */ public int Metricwidth(Context context){ DisplayMetrics metric = new DisplayMetrics(); metric = context.getResources().getDisplayMetrics(); return metric.widthPixels; } //獲取直接獲取屏幕的實際寬度 public void GetrealScreenwidth(Context context){ DisplayMetrics metric = new DisplayMetrics(); metric = context.getResources().getDisplayMetrics(); setScreensize(metric.widthPixels); } //設置線性佈局下的線性高度 public void llinearlayoutheight(int px, LinearLayout linearLayout) { LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) linearLayout.getLayoutParams(); if(screensize != 0) { layoutParams.height = px * screensize / screenwidth; linearLayout.setLayoutParams(layoutParams); } } /*********************** 控件設置 */ //自動設置設置字體的大小 public int autosettextsize(int sp){ if(screensize != 0) { return sp * screensize / screenwidth; } else { return sp; } } /** * 相對佈局中的不一樣設置高度 */ //設置相對佈局下的相對佈局高度 public void relativeLayoutheight(int px, RelativeLayout relativeLayout) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams(); if(screensize != 0) { layoutParams.height = px * screensize / screenwidth; relativeLayout.setLayoutParams(layoutParams); } } //設置相對佈局中的相對高度帶Margintop設置 public void relativeLayoutheightwithmargintop(int px,int margintop, RelativeLayout relativeLayout){ RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams(); if(screensize != 0) { layoutParams.height = px * screensize / screenwidth; layoutParams.topMargin = margintop * screensize / screenwidth; relativeLayout.setLayoutParams(layoutParams); } } public void relativeLayoutheightmargintop(int margintop, RelativeLayout relativeLayout){ RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) relativeLayout.getLayoutParams(); if(screensize != 0) { layoutParams.topMargin = margintop * screensize / screenwidth; relativeLayout.setLayoutParams(layoutParams); } } //設置相對佈局下的線性佈局高度 public void rlinearlayoutheight(int px, LinearLayout linearLayout) { RelativeLayout.LayoutParams relativelayout = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams(); if(screensize != 0) { relativelayout.height = px * screensize / screenwidth; linearLayout.setLayoutParams(relativelayout); } } public void rlinearlayoutheightwithmargintop(int px,int margintop,LinearLayout linearLayout) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams(); if(screensize != 0) { layoutParams.height = px * screensize / screenwidth; layoutParams.topMargin = margintop * screensize / screenwidth; linearLayout.setLayoutParams(layoutParams); } } public void rlinearlayoutheightmargintop(int margintop,LinearLayout linearLayout) { RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams(); if(screensize != 0) { layoutParams.topMargin = margintop * screensize / screenwidth; linearLayout.setLayoutParams(layoutParams); } } }
在這裏我來舉個例子:
Autosize autosize = new Autosize(); autosize.GetrealScreenwidth(getActivity()); RelativeLayout tophome = (RelativeLayout) findViewById(R.id.tophome); autosize.relativeLayoutheight(88,tophome);
步驟:
必定要注意你究竟是哪一個佈局下的一個佈局,必須找到父view纔可使用!若是想知道爲何的話,你們能夠去找layoutparams有關的內容!
那個撒,你看我如此賣命地寫博客,並且仍是本身在攻克難點,就來關注個人博客唄!