編輯:關於Android編程
在軟件開發的過程中,為了讓軟件在不同的場景下都可以使用,所以機型適配是不可或缺並且非常重要耗時的一個環節。
1,Android的版本
2.手機廠商
3.屏幕的尺寸
4.網絡的制式
5.語言
6.國家
7.硬件設備
8.運行商
關於現在要考慮的機型適配的問題,就目前來說,我還只能解決一些方面
1.在Android的工程下的res目錄下進行設備性能支持的適配.
我們通過在res目錄下新建不同的文件夾,設定不同的布局/字符串/圖片/語言等等,來適配不同的機型.
1.圖片適配屏幕
2.界面橫豎屏切換屏幕
3.屏幕寬高度大小適配
4.語言的適配
2.. Android提供了自動的設備檢測功能,能夠根據當前設備的一些參數信息,進行動態的資源的加載,從而實現機型適配;
在Android的工程目錄下,我們可以看到有不同的文件夾hdpi mdpi xdpi xxhdpi xxxhdpi,存放著相同的圖片,他是在不同的屏幕的分辨率下,顯示不同的圖片.
涉及到的知識點:
1.密度dpi越大,同一個像素尺寸的圖片顯示的越小;
2.手機的屏幕密度越小(分辨率卻低),同一個圖片顯示的就大了。
3.高密度手機使用大圖片;低密度手機用小圖片;
4.dpi的計算 .
dp/sp的概念:
dp/dip:Android中,定義一套單位dp,以mdpi為標准,進行自動
運算的像素數值;
例如:5dp, 在mdpi的手機上,就是5px
在xhdpi的手機上,就是15px
sp: scalable pixel 可縮放的px, 用於文本的處理.運算規則
和dp相似
px = dp * (dpi / 160) 已知dp求px
已知px 求dp, dp = px / (dpi / 160)
有關三者之間的關系:
http://www.jianshu.com/p/913943d25829
5.以mdpi為基准,進行尺寸的縮放;
縮放規則:
mdpi 1 原始尺寸
ldpi 0.75倍 尺寸
hdpi 1.5倍 尺寸
xhdpi 2倍 尺寸
xxhdpi 3倍
xxxhdpi 4倍
6.目前建議,采用高清大圖進行設計,分辨率低的會自動縮小,圖片縮小不會失真.
我們可以在res目錄下,新建values文件,進行不同屏幕尺寸的適配(small/nomal/large/xlarge),我們可以新建layout-small文件夾,設計不同的布局,我們也可以在values-small文件下,新建不同的values資源文件,在不同的屏幕尺寸下顯示不同的資源.
新建不同的values語言文件,適配不同種語言的Android系統.
1).在android3.0之後出現了一套新的屏幕尺寸適配規則: swXXXdp, wXXXdp, hXXXdp
2).可以控制的程度更細,能夠精確適配;可以覆蓋指定數值以及更大的尺寸
swxxxdp :表示屏幕的最短邊是xxxdp的屏幕,都適配.
wxxxdp:表示平行於地面的邊的寬度,在表示的范圍內,將會進行布局適配;
如: w240dp; w320dp,w480dp,w600dp; 表示的大小:
[240,320),…[600,………..)
hxxxdp:與sxxxxdp同樣的道理.
sw比w/h的優先級高
// 獲取屏幕的高寬,dp,px public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TextView textView = (TextView) findViewById(R.id.device_text); // DisplayMetrics中存儲的是有關屏幕的相關參數 DisplayMetrics dm = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(dm); int w = dm.widthPixels; // 屏幕寬度 int h = dm.heightPixels; // 屏幕高度 int densityDpi = dm.densityDpi; // 屏幕dpi() float xdpi = dm.xdpi; // x dpi float ydpi = dm.ydpi; // y dpi // px = dp * (dpi / 160) 已知dp求px // 已知px 求dp, dp = px / (dpi / 160) // 已知dm.density = dpi / 160 float wDp = w / dm.density; Log.d("TAG", "onCreate: w " + wDp + "dp"); textView.setText(Float.toString(wDp)); }
1.使用 wrap_content, match_parent 或者 dp單位尺寸
wrap_content,match_parent以及dp尺寸均會進行縮放,如 100dp 對應 medium dpi,那麼對於hdpi就會放到1.5倍,字體必須使用 sp 單位,因為能夠縮放.
2.不要在代碼中硬編碼尺寸
因為性能和簡單要求,Android系統內部均使用像素進行維護,例如在一個設備上執行 View.getWidth()返回10像素,不要將這個數值作為硬編碼的常數,因為可能在高密度的設備上,返回的值可能會是15.
案例:
/** * 在代碼中使用尺寸的方式 * 需要進行代碼適配 */ public class CodeSizeActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_code_size); ViewGroup group = (ViewGroup) findViewById(R.id.my_layout); TextView textView = new TextView(this); // LayoutParams 所有的Android標准容器,都有自己的LayoutParams // 控件添加到哪種容器類型,就使用這個類型的LayoutParams LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( (int) dp2px(this, 200), // 直接寫數值 屬於硬編碼 (int) dp2px(this, 50) // 數字都是 像素單位,!!! 像素單位不支持機型適配; ); textView.setLayoutParams(lp); textView.setText("Hello World by Zhang sir"); textView.setBackgroundColor(0xFFb99393); group.addView(textView); } /** * 實現機型適配,可以指定數值, 根據手機屏幕密度, * 生成像素單位, 用於代碼中的尺寸設置 */ public static float dp2px(Context context, int dp) { DisplayMetrics outMetrics = new DisplayMetrics(); // 版本適配 if (Build.VERSION.SDK_INT >= 17) { DisplayManager displayManager = (DisplayManager) context.getSystemService( Context.DISPLAY_SERVICE ); displayManager.getDisplay(0).getMetrics(outMetrics); } else { WindowManager manager = (WindowManager) context.getSystemService(WINDOW_SERVICE); manager.getDefaultDisplay().getMetrics(outMetrics); } float px = dp * outMetrics.density; return px; } }
3.不使用絕對布局
4.使用修飾符定位尺寸和密度資源
5.代碼中對像素進行縮放
6*.利用尺寸資源來優化layout布局
建議將layout中的尺寸數值,放到獨立的尺寸資源文件dimens.xml中,這樣就可以利用密度、尺寸來進行屏幕尺寸適配而不用創建多個layout.
/** * 可以把這個當做工具類. * 實現機型適配,可以指定數值,根據手機屏幕密度 * 生成像素單位,用於代碼中的尺寸設置 */ public static float dp2Px(Context context, int dp) { DisplayMetrics metrics = new DisplayMetrics(); if (Build.VERSION.SDK_INT >= 17) { DisplayManager manager = (DisplayManager) context.getSystemService(context.DISPLAY_SERVICE); manager.getDisplay(0).getMetrics(metrics); } else { WindowManager manager = ((WindowManager) context.getSystemService(WINDOW_SERVICE)); manager.getDefaultDisplay().getMetrics(metrics); } float px = dp * metrics.density; return px; }
1. 機型適配中的版本適配,使用數字來進行判斷的. 因為在SDK中是有些錯誤的地方 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { } 會直接崩潰 Build.VERSION_CODES.N:在AndroidAPI1出現的,在Android5.0的手機會找不到這個變量.因為Android5.0找不到這個變量 2.if (Build.VERSION.SDK_INT >= 24) { android.icu.text.SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); } else { java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy年MM月dd日"); } java中采用堆棧的方式來存儲類,在加載類之前,會檢查所有的類是否存在;所以對於程序,如果有上述代碼,會直接崩潰 Android中不會檢查所有的類,會執行到 if (Build.VERSION.SDK_INT >= 24) 再去加載類
在清單文件中使用
要區別
沒睡著覺,起來更篇文章吧哈哈!首先祝賀李宗偉擊敗我丹,雖然我是支持我丹的,但是他也不容易哈哈,值得尊敬的人!切入正題:這一篇來介紹個自定義廣播接收者。通常我們在外撥電話的
相信很多人都用過開源項目,特別是android studio普及以後,使用開源庫更方便簡單。而如何上傳開源庫到jcenter供大家方便使用,雖然網上也有教程,但還是遇坑
1、前言 等級信號狀態的View在現在的Android系統中非常的常見,比如手機右上角的電池狀態的圖標就非常的經典,有幾種狀態,到了快沒電的時候有些還會閃爍提示用戶充電;
前言:最近公司C輪融資成功了,移動團隊准備擴大一下,需要招聘Android開發工程師,陸陸續續面試了幾位Android應聘者,面試過程中聊到性能優化中如何避免內存洩漏問題