android獲取屏幕高寬
㈠ Android 如何正確的獲取屏幕高度
我們需要獲取Android手機或Pad的屏幕的物理尺寸,以便於界面的設計或是其他功能的實現。下面就介紹講一講如何獲取屏幕的物理尺寸
下面的代碼即可獲取屏幕的尺寸。
在一個Activity的onCreate方法中,寫入如下代碼:
java">DisplayMetricsmetric=newDisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
intwidth=metric.widthPixels;//屏幕寬度(像素)
intheight=metric.heightPixels;//屏幕高度(像素)
floatdensity=metric.density;//屏幕密度(0.75/1.0/1.5)
intdensityDpi=metric.densityDpi;//屏幕密度DPI(120/160/240)
但是,需要注意的是,在一個低密度的小屏手機上,僅靠上面的代碼是不能獲取正確的尺寸的。比如說,一部240x320像素的低密度手機,如果運行上述代碼,獲取到的屏幕尺寸是320x427。
因此,研究之後發現,若沒有設定多解析度支持的話,Android系統會將240x320的低密度(120)尺寸轉換為中等密度(160)對應的尺寸,這樣的話就大大影響了程序的編碼。
所以,需要在工程的AndroidManifest.xml文件中,加入supports-screens節點,具體的內容如下:
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:resizeable="true"
android:anyDensity="true"/>
這樣的話,當前的Android程序就支持了多種解析度,那麼就可以得到正確的物理尺寸了。
importandroid.app.Activity;
importandroid.os.Bundle;
importandroid.util.DisplayMetrics;
importandroid.widget.TextView;
{
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
//setContentView(newMyView(this));
//定義DisplayMetrics對象
setContentView(R.layout.main);
DisplayMetricsdm=newDisplayMetrics();
//取得窗口屬性
getWindowManager().getDefaultDisplay().getMetrics(dm);
//窗口的寬度
intscreenWidth=dm.widthPixels;
//窗口高度
intscreenHeight=dm.heightPixels;
TextViewtextView=(TextView)findViewById(R.id.tv1);
textView.setText("屏幕寬度:"+screenWidth+" 屏幕高度:"+screenHeight);
}
}
㈡ 怎樣獲取Android手機屏幕的大小(解析度、密度)
下面的代碼即可獲取屏幕的尺寸: 在一個Activity的onCreate方法中,編寫以下代碼: DisplayMetrics metric = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getMetrics(metric); int width = metric.widthPixels; // 寬度(PX) int height = metric.heightPixels; // 高度(PX) float density = metric.density; // 密度(0.75 / 1.0 / 1.5) int densityDpi = metric.densityDpi; // 密度DPI(120 / 160 / 240) 需要注意的是,在一個低密度的小屏手機上,僅靠上面的代碼是不能獲取正確的尺寸的。 所以,需要在工程的AndroidManifest.xml文件中,加入supports-screens節點,如下: 這樣當前的Android程序就支持了多種解析度,那麼就可以得到正確的物理尺寸了。
㈢ 聊聊獲取屏幕高度這件事
說起獲取屏幕高度,或許你有所理解,但這個高度范圍究竟指的是應用顯示區域的高度,還是手機屏幕的高度呢?我們先來回顧一下平時使用獲取高度的方法:
以上三種方法的效果一致,只是寫法略有不同。
或許你使用的是這種方法:
這個方法在系統版本大於等於Android 4.2時,會使用getRealMetrics(getRealSize)來獲取屏幕高度。那麼這里發生了什麼?為什麼會這樣呢?
其實在Android 4.0時,引入了虛擬導航鍵。如果你繼續使用getMetrics之類的方式獲取高度,獲取的高度會去除導航欄的高度。
由於在4.0和4.2之間並沒有getRealMetrics這個方法,所以當時甚至需要添加適配代碼:
現在應該沒有人還在適配4.4甚至5.0以下的機型了吧?所以歷史的包袱可以放下了。
上面方法名都是getScreenHeight,但這個高度范圍到底和你需要的是否一致呢?這需要開發時注意。我的習慣是ScreenHeight指應用顯示的高度,不包括導航欄(非全屏下),RealHeight指包含導航欄和狀態欄的高度(getRealMetrics)。
PS:以前也使用過AndroidUtilCode這個工具庫,裡面將前者方法名定義為getAppScreenHeight,後者為getScreenHeight。也是很直觀的方法。
下文中我會以自己的習慣,使用ScreenHeight和RealHeight來代表兩者。
我印象中華為手機很早就使用了虛擬導航鍵,如下圖(圖片來源):
比較特別的是,當時華為的導航欄還可以顯示和隱藏,注意圖中左下角的箭頭。點擊可以隱藏,上滑可以顯示。即使這樣,使用getScreenHeight也可以准確獲取高度,隱藏了ScreenHeight就等於RealHeight。
上述的這一切在「全面屏」時代到來之前,沒有什麼問題。
小米MIX的發布開啟了全面屏時代(16年底),以前的手機都是16:9的,記得雷布斯在發布會上說過,他們費了很大的力氣說服了谷歌去除了16:9的限制(從Android 7.0開始)。
全面屏手機是真的香,不過隨之也帶來適配問題。首當其沖的就是劉海屏,各家有各自的獲取劉海區域大小的方法。主要原因還是國內競爭的激烈,各家為了搶占市場,先於谷歌定製了自己的方案。這一點讓人想起了萬惡的動態許可權適配。
其實在劉海屏之下,還隱藏一個導航欄的顯示問題,也就是本篇的重點。全面屏追求更多的顯示區域,隨之帶來了手勢操作。在手勢操作模式下,導航欄是隱藏狀態。
本想著可以和上面提到的華為一樣,隱藏獲取的就是RealHeight,顯示就是減去導航欄高度的ScreenHeight。然而現實並不是這樣,下表是我收集的一些全面屏手機各高度的數據。
ScreenHeight一欄中括弧內表示顯示導航欄時獲取的屏幕高度。
大致的規律總結如下:
其中vivo手機,屏幕高度加狀態欄高度大於真實高度(2201 + 84 > 2280)。本以為差值79是劉海高度,但查看vivo文檔後發現,vivo劉海固定27dp(81px),也還是對不上。
一加6最奇怪,三種設置模式。使用側邊全屏手勢時底部有一個小條,NavigationBar高度變為42。(2159 + 42 = 2075 + 126 = 2201)也就是說這種模式也屬於有導航欄的情況。
這時如果你需要獲取准確的ScreenHeight,只有通過RealHeight - NavigationBar來實現了。
所以首先需要判斷當前導航欄是否顯示,再來決定是否減去NavigationBar高度。
先看看老牌的判斷方法如下:
此方法通過比較ScreenHeight和RealHeight是否相等來判斷。如果對比上面表中的數據,那隻有OPPO Find X可以判斷成功。也有一些方法通過ScreenHeight和RealHeight差值來計算導航欄高度。顯然這些方法已無法再使用。
所以搜索了一下相關信息,得到了下面的代碼:
可以看到包含了華為、小米、vivo、oppo、三星甚至諾基亞的判斷。這就是適配的現實狀況,不要妄想尋找什麼通用方法,老老實實一個個判斷吧。畢竟幺蛾子就是這些廠家搞出來的,廠家魔改教你做人。
這種方法在上面的測試機中都親測准確有效。
不過這個判斷方法不夠嚴謹,比如其他品牌手機使用此方法,那麼結果都是false。用這樣的結果來計算高度顯得不夠嚴謹。
根據前面提到問題發生的原因是全面屏帶來的(7.0及以上)。所以我們可以先判斷是否是全面屏手機(屏幕長寬比例超過1.86以上),然後判斷是否顯示導航欄,對於不確定的機型,我們還是使用原先的ScreenHeight。盡量控制影響范圍。
我整理的代碼如下(補充了一加、錘子手機判斷):
有人會問,這些key都是哪裡來的?畢竟我在廠商文檔也沒有翻到。
我能想到的辦法是查看SettingsProvider,它是提供設置數據的Provider,分有Global、System、Secure三種類型,上面代碼中可以看到不同品牌存放在的類型都不同。我們可以通過adb命令查看所有數據,根據navigation等關鍵字去尋找。比如查看Secure的數據:
或者:
這樣如果有上面兼容不到的機型,可以使用這個方法適配。也歡迎你的補充反饋。
費了這么大的勁獲取到了准確的高度,可能你會說,還不如直接獲取ContentView的高度:
這個結果和上述計算的高度一致,唯一的限制是需要在onWindowFocusChanged之後調用,否則高度為0。這個我們可以根據實際情況自行選用。
第二種情況就是狀態欄強制為黑色。這里我懷疑因為這個設置,導致在有劉海的手機上,ScreenHeight不包含狀態欄高度。
最糟糕的是第三種,隱藏後狀態欄在劉海外。例如Redmi K30在開啟後,ScreenHeight為2174,RealHeight為2304,而關閉時為2175和2400。這下連萬年不變的RealHeight也變化了,這太不real了,大家自行體會。不過目前發現未影響適配方案,不知其他手機如何。
對於是否隱藏劉海,其實也是有各家的判斷的,比如小米:
getSystem源碼如下:
它不受資源覆蓋的影響,我們可以通過它將值轉換回來。
本篇看似聊的獲取高度這件事,其實伴隨導航欄的發展演進,核心是是如何判斷導航欄是否顯示。
通過上面的介紹,總結一下就是在「全面屏時代」,如果你想獲取屏幕高度,就不要使用ScreenHeight了。否則會出現UI展示上的問題。而且這種問題,線上也不會崩潰,難以發現。以前在支付寶中就發現過PopupWindow彈出高度不正確的問題,過了好久才修復了。
至於屏幕寬度,也不清楚隨著折疊屏、環繞屏的到來會不會造成影響。但願不要吧,碎片化越來越嚴重了。
最後,如果本文對你有啟發有幫助,點個贊可好?
㈣ android 開發中 怎麼用js獲取手機屏幕高度
webview.addjavascriptinterface可以調用android代碼
android可以獲得屏幕高度
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
int height = dm.heightPixels//這個就是屏幕高度了。
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
這個就創立了一個介面名,叫「Android」,運行在WebView中的JS代碼可以通過這個名字調用WebAppInterface類中的showToast()方法:
<input type="button" value="Say hello" onClick="showAndroidToast('Hello Android!')" />
<script type="text/javascript">
function showAndroidToast(toast)
{
Android.showToast(toast);
}
</script>
㈤ Android手機js獲取屏幕尺寸不準,導致計算的問題
Android中可以通過三種方式獲到屏幕大小:
1、通過WindowManager獲取
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
System.out.println("heigth : " + dm.heightPixels);
System.out.println("width : " + dm.widthPixels);
2、通過Resources獲取
DisplayMetrics dm2 = getResources().getDisplayMetrics();
System.out.println("heigth2 : " + dm2.heightPixels);
System.out.println("width2 : " + dm2.widthPixels);
3、通過Display 獲取屏幕的默認解析度
Display display = getWindowManager().getDefaultDisplay();
System.out.println("width-display :" + display.getWidth());
System.out.println("heigth-display :" + display.getHeight());