首頁 > 軟體

Android全面屏適配與判斷超詳細講解

2023-01-22 14:01:33

1.全面屏的適配

全面屏出現後,如果不做適配,螢幕上會出現上下黑邊,影響視覺效果。

針對此問題,Android官方提供了適配方案,即提高App所支援的最大螢幕縱橫比,實現起來也比較簡單,在AndroidManifest.xml中做如下設定即可,在AndroidManifet裡的下宣告:

<meta-data android:name="android.max_aspect"  
           android:value="ratio_float"/>

將ratio_float設定為2.1即可適配一眾全螢幕手機,即:

 <meta-data
            android:name="android.max_aspect"
            android:value="2.1" />

2.判斷是否為全面屏

很多的手機是有虛擬導航欄的,特別是華為手機,有人提議通過判斷是否含有虛擬導航欄,不就可以判斷是否為全面屏了嗎?

/**
     * 判斷裝置是否存在NavigationBar(虛擬導航欄)
     *
     * @return true 存在, false 不存在
     */
    public static boolean deviceHasNavigationBar() {
        boolean haveNav = false;
        try {
            //1.通過WindowManagerGlobal獲取windowManagerService
            // 反射方法:IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService();
            Class<?> windowManagerGlobalClass = Class.forName("android.view.WindowManagerGlobal");
            Method getWmServiceMethod = windowManagerGlobalClass.getDeclaredMethod("getWindowManagerService");
            getWmServiceMethod.setAccessible(true);
            //getWindowManagerService是靜態方法,所以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;
    }

通過檢驗發現,此方法並不能判斷是否為全面屏,因為全面屏的手機通過以上方法,判斷的值為:true。

因此,需要從其他方面進行判斷,全面屏與傳統屏的區別在於,螢幕的縱橫比,所以,可以從縱橫比方面做出判斷,詳細程式碼如下:

 /**
     * 判斷是否是全面屏
     */
    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的,都不會是全面屏。。。
        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相容適配有虛擬導航欄手機和全面屏的顯示時,底部被虛擬導航欄遮蓋,或者全螢幕手機下方有間隙。

3.全螢幕手機的虛擬導航和全面屏手勢的判斷

全螢幕手機手勢是一特色,但也還是有習慣了用虛擬導航欄的,因此在判斷是否為全螢幕手機的基礎上,需要做虛擬導航欄的適配;

判斷是否啟用虛擬導航的方法:

  /**
     * 判斷全面屏是否啟用虛擬鍵盤
     */
    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;
    }

直接用這個方法,會發現不起作用,需要在 onCreate(Bundle savedInstanceState)方法中加入一下程式碼:

  //設定底部導航欄顏色
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getWindow().setNavigationBarColor(ContextCompat.getColor(this, R.color.white));
        }

這個既可以作為修改導航欄顏色,也是必須的,否則判斷是否啟用虛擬導航的方法的無效。

到此這篇關於Android全面屏適配與判斷超詳細講解的文章就介紹到這了,更多相關Android全面屏適配內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com