Android全面屏適配與判斷超詳細(xì)講解
1.全面屏的適配
全面屏出現(xiàn)后,如果不做適配,屏幕上會(huì)出現(xiàn)上下黑邊,影響視覺(jué)效果。
針對(duì)此問(wèn)題,Android官方提供了適配方案,即提高App所支持的最大屏幕縱橫比,實(shí)現(xiàn)起來(lái)也比較簡(jiǎn)單,在AndroidManifest.xml中做如下配置即可,在AndroidManifet里的下聲明:
<meta-data android:name="android.max_aspect" android:value="ratio_float"/>
將ratio_float設(shè)置為2.1即可適配一眾全面屏手機(jī),即:
<meta-data android:name="android.max_aspect" android:value="2.1" />
2.判斷是否為全面屏
很多的手機(jī)是有虛擬導(dǎo)航欄的,特別是華為手機(jī),有人提議通過(guò)判斷是否含有虛擬導(dǎo)航欄,不就可以判斷是否為全面屏了嗎?
/** * 判斷設(shè)備是否存在NavigationBar(虛擬導(dǎo)航欄) * * @return true 存在, false 不存在 */ public static boolean deviceHasNavigationBar() { boolean haveNav = false; try { //1.通過(guò)WindowManagerGlobal獲取windowManagerService // 反射方法:IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService(); Class<?> windowManagerGlobalClass = Class.forName("android.view.WindowManagerGlobal"); Method getWmServiceMethod = windowManagerGlobalClass.getDeclaredMethod("getWindowManagerService"); getWmServiceMethod.setAccessible(true); //getWindowManagerService是靜態(tài)方法,所以invoke null Object iWindowManager = getWmServiceMethod.invoke(null); //2.獲取windowMangerService的hasNavigationBar方法返回值 // 反射方法:haveNav = windowManagerService.hasNavigationBar(); Class<?> iWindowManagerClass = iWindowManager.getClass(); Method hasNavBarMethod = iWindowManagerClass.getDeclaredMethod("hasNavigationBar"); hasNavBarMethod.setAccessible(true); haveNav = (Boolean) hasNavBarMethod.invoke(iWindowManager); } catch (Exception e) { e.printStackTrace(); } return haveNav; }
通過(guò)檢驗(yàn)發(fā)現(xiàn),此方法并不能判斷是否為全面屏,因?yàn)槿嫫恋氖謾C(jī)通過(guò)以上方法,判斷的值為:true。
因此,需要從其他方面進(jìn)行判斷,全面屏與傳統(tǒng)屏的區(qū)別在于,屏幕的縱橫比,所以,可以從縱橫比方面做出判斷,詳細(xì)代碼如下:
/** * 判斷是否是全面屏 */ private volatile static boolean mHasCheckAllScreen; private volatile static boolean mIsAllScreenDevice; public static boolean isAllScreenDevice(Context context) { if (mHasCheckAllScreen) { return mIsAllScreenDevice; } mHasCheckAllScreen = true; mIsAllScreenDevice = false; // 低于 API 21的,都不會(huì)是全面屏。。。 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { return false; } WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); if (windowManager != null) { Display display = windowManager.getDefaultDisplay(); Point point = new Point(); display.getRealSize(point); float width, height; if (point.x < point.y) { width = point.x; height = point.y; } else { width = point.y; height = point.x; } if (height / width >= 1.97f) { mIsAllScreenDevice = true; } } return mIsAllScreenDevice; }
例如:此判斷在PopupWindow兼容適配有虛擬導(dǎo)航欄手機(jī)和全面屏的顯示時(shí),底部被虛擬導(dǎo)航欄遮蓋,或者全面屏手機(jī)下方有間隙。
3.全面屏手機(jī)的虛擬導(dǎo)航和全面屏手勢(shì)的判斷
全面屏手機(jī)手勢(shì)是一特色,但也還是有習(xí)慣了用虛擬導(dǎo)航欄的,因此在判斷是否為全面屏手機(jī)的基礎(chǔ)上,需要做虛擬導(dǎo)航欄的適配;
判斷是否啟用虛擬導(dǎo)航的方法:
/** * 判斷全面屏是否啟用虛擬鍵盤 */ private static final String NAVIGATION = "navigationBarBackground"; public static boolean isNavigationBarExist(@NonNull Activity activity) { ViewGroup vp = (ViewGroup) activity.getWindow().getDecorView(); if (vp != null) { for (int i = 0; i < vp.getChildCount(); i++) { vp.getChildAt(i).getContext().getPackageName(); if (vp.getChildAt(i).getId()!=-1&& NAVIGATION.equals(activity.getResources().getResourceEntryName(vp.getChildAt(i).getId()))) { return true; } } } return false; }
直接用這個(gè)方法,會(huì)發(fā)現(xiàn)不起作用,需要在 onCreate(Bundle savedInstanceState)方法中加入一下代碼:
//設(shè)置底部導(dǎo)航欄顏色 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.white)); }
這個(gè)既可以作為修改導(dǎo)航欄顏色,也是必須的,否則判斷是否啟用虛擬導(dǎo)航的方法的無(wú)效。
到此這篇關(guān)于Android全面屏適配與判斷超詳細(xì)講解的文章就介紹到這了,更多相關(guān)Android全面屏適配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 實(shí)現(xiàn)圖片模糊、高斯模糊、毛玻璃效果的三種方法
在前幾天寫(xiě)過(guò)一個(gè)使用glide-transformations的方法實(shí)現(xiàn)高斯模糊的方法,今天偶然間有發(fā)現(xiàn)一個(gè)大神寫(xiě)的另一個(gè)方法,感覺(jué)挺不錯(cuò)的,分享一下2016-12-12Android ImageView的selector效果實(shí)例詳解
這篇文章主要介紹了Android ImageView的selector效果實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07Android App中自定義View視圖的實(shí)例教程
這篇文章主要介紹了Android App中自定義View視圖的實(shí)例教程,詳細(xì)講解了如何在創(chuàng)建View中定義各種鎖需要的樣式屬性,需要的朋友可以參考下2016-04-04RxJava實(shí)戰(zhàn)之訂閱流基本原理示例解析
這篇文章主要為大家介紹了RxJava實(shí)戰(zhàn)之訂閱流基本原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12android中Intent傳值與Bundle傳值的區(qū)別詳解
本篇文章是對(duì)android中Intent傳值與Bundle傳值的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05淺談android獲取存儲(chǔ)目錄(路徑)的幾種方式和注意事項(xiàng)
今天小編就為大家分享一篇淺談android獲取存儲(chǔ)目錄(路徑)的幾種方式和注意事項(xiàng),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08