編輯:關於Android編程
前言:前面幾篇總結一些TV上的小Sample,開源到GitHub:https://github.com/hejunlin2013/TVSample, 點擊鏈接,可以持續關注。今天總結下TV上屏幕適配.:
看下Agenda:
一、屏幕適配的一些背景知識
二、TV屏幕適配怎麼適配?有哪些規則?
三、多屏幕適配,android讀取res/drawable優先級是什麼?
四、屏幕分辨率及density 、densityDpi代碼
一、屏幕適配的一些背景知識
介紹幾個在Android屏幕適配上非常重要的名詞:
什麼是屏幕尺寸、屏幕分辨率、屏幕像素密度?
屏幕尺寸是指屏幕對角線的長度。單位是英寸,1英寸=2.54厘米;
屏幕分辨率是指在橫縱向上的像素點數,單位是px,1px=1像素點,一般是縱向像素橫向像素,如1280×720;
屏幕像素密度是指每英寸上的像素點數,單位是dpi,即“dot per inch”的縮寫,像素密度和屏幕尺寸和屏幕分辨率有關。
例如:計算Nexus5的屏幕像素密度:
屏幕尺寸:4.95inch、分辨率:1920×1080,屏幕像素密度:445
和官方給出的一樣,說明我們計算正確。
2
什麼是dp、dip、dpi、sp、px?之間的關系是什麼?
dip:Density Independent Pixels(密度無關像素)的縮寫。以160dpi為基准,1dp=1px
dp:同dip
dpi:屏幕像素密度的單位,“dot per inch”的縮寫
px:像素,物理上的絕對單位
sp:Scale-Independent Pixels的縮寫,可以根據文字大小首選項自動進行縮放。Google推薦我們使用12sp以上的大小,通常可以使用12sp,14sp,18sp,22sp,最好不要使用奇數和小數。
說明:如果A設備的參數為480×320,160dpi,B設置的參數為800×480,240dpi。我們要畫出一條和屏幕寬度一樣長的直線,如果使用px作為單位,必須在A設備上設置為320px,在B設備上設置480px。但是如果我們使用dp作為單位,由於以160dpi為基准,1dp=1px,所以A設備上設置為320dp就等於屏幕寬度(320px),在B設備上設置為320dp就等於320×(240/160)=480px,即B設備的屏幕寬度。這樣,使用dp作為單位就可以實現簡單的屏幕適配。這知識一種巧合,也有B設備的像素密度不是這樣剛剛好的,就需要我們運用別的屏幕適配技術。
3
什麼是mdpi、hdpi、xdpi、xxdpi、xxxdpi?如何計算和區分?
用於區分不同的像素密度。
在Google官方開發文檔中,說明了mdpi:hdpi:xhdpi:xxhdpi:xxxhdpi=2:3:4:6:8的尺寸比例進行縮放。例如,一個圖標的大小為48×48dp,表示在mdpi上,實際大小為48×48px,在hdpi像素密度上,實際尺寸為mdpi上的1.5倍,即72×72px,以此類推。
二、TV屏幕適配怎麼適配?有哪些規則?
先看下一些盒子的分辨率
屏幕密度值未列入其中,第二欄的說明最後的值,就是通過在不同分辨率下,屏幕密度值不同,得到的不同結果,可以看到同樣是1280*720的盒子,由於屏幕密度值不同,對得到的dpi不同。
於是就有了這種適配,在此之前,無論是做Android TV開發,還是做phone端開發,永遠不要迷信大家說的萬能適配,對於圖片之類的素材,根本沒有所謂的捷徑。所以要了解,當apk,運行在android系統中時,系統是如何讀取各drawable的先後順序的。以之前奇葩的小米2代為例,相比正常的盒子英菲克I9,同樣1280*720,dpi一個是160,一個是213dpi,當圖片放到hdpi下,發現在小米2代,圖片永遠顯示不正常。
三、多屏幕適配,android讀取res/drawable優先級是什麼?
以下是我的總結(按讀取優先級順序排列):
1.語言(zh-rCN)
2.smallestWidth最短可用寬度(與屏幕方向無關)
3.availablewidth(w-dp)(與屏幕方向有關)
4.values/drawable-1920x1080
5. drawable-213dpi
6. ldpi/mdpi/hdpi/xhdpi/xxhdpi
說明:
對於第一項:可以看到先從語言類開始讀取,如果做國際化的,可以關注此項,第1項暫時不看。
對於第二項:就是values-sw540dp,諸如此類,sw代表最短可用寬度,注意,是和屏幕方向無關,如一個分辨率為1280*720,sw就是720,假設它的density(屏幕密度)為2,通過公式720/2=360, 這個360就是densityDpi(屏幕密度DPI),所以,在適配時,用values-sw360dp,適配就行了。那問題來了,drawable要不要這樣呢?對於文章開頭那個表格,360dp是屬於xxhdpi,所以把圖放到對應有xxhdpi就能完成適配。
對於第三項:諸如values-w540dp/values-h,這種是有和屏幕方向有關,第一個後綴wdp如layout-w600dp, values-w600dp帶這樣後綴的資源文件的資源文件制定了屏幕寬度的大於Ndp的情況下使用該資源文件,但它和swdp不同的是,當屏幕橫向縱向切換時,屏幕的寬度是變化的,以變化後的寬度來與N相比,看是否使用此資源文件下的資源。第二個後綴hdp如layout-h600dp, values-h600dp這個後綴的使用方式和wdp一樣,隨著屏幕橫縱向的變化,屏幕高度也會變化,根據變化後的高度值來判斷是否使用hdp ,但這種方式很少使用,因為屏幕在縱向上通常能夠滾動導致長度變化,不像寬度那樣基本固定,因為這個方法靈活性不是很好,google官方文檔建議盡量少使用這種方式。
第四項,是指寫死對應的分辨率,android碎片化嚴重的情況下,顯然不可取
第五項,這個就是為解決同一分辨率下,不同的density引起的適配問題。如上面的小米2代解決方案,最後就是加上這個資源目錄,換了一個圖(圖片比原來小),問題解決。
第六項,就是平時經常用到的,通常是這種方法不能解決適配的需要時,才配合前面的幾種一起使用解決適配問題。
四、屏幕分辨率及density、densityDpi代碼
mText = (TextView) findViewById(R.id.text);
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int width = metric.widthPixels; // 屏幕寬度(像素)
int height = metric.heightPixels; // 屏幕高度(像素)
float density = metric.density; // 屏幕密度(0.75 / 1.0 / 1.5)
int densityDpi = metric.densityDpi; // 屏幕密度DPI(120 / 160 / 240)
String info = "手機型號: " + android.os.Build.MODEL + ",\nSDK版本:"
+ android.os.Build.VERSION.SDK + ",\n系統版本:"
+ android.os.Build.VERSION.RELEASE + "\n屏幕寬度(像素): " +width + "\n屏幕高度(像素): " + height + "\n屏幕密度: " +density+"\n屏幕密度DPI: "+densityDpi;
Log.d("system Enviriment", info);
mText.setText(info);
著手開發一款應用的時候,設置或者菜單頁面是可能需要的,但是,那重復的布局會很令人苦惱。新手可能會一項項的重復繪制,有經驗的你或許會用到include,或者用到組合控件。除
從今天起,我要分析React Native for Android的源碼。本系列主要是從使用和源碼分析的角度來一步步的剖析React Native Android。當然,
本文介紹Android平台進行數據存儲的五大方式,分別如下:1 使用SharedPreferences存儲數據2 文件存儲數據 &nbs
原理最近用socket寫了一個消息推送的demo,在這裡和大家分享一下。主要實現了:一台手機向另外一台手機發送消息,這兩台手機可以隨時自由發送文本消息進行通信,類似我們常