91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android全面屏適配怎么實現

發布時間:2023-03-01 17:42:07 來源:億速云 閱讀:168 作者:iii 欄目:開發技術

今天小編給大家分享一下Android全面屏適配怎么實現的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

    Android P前后

    對于Android P,其實也就android 8.0和android 9.0兩個版本,因為是從android 8.0開始流行的,各做各的,然后在9.0的時候google給出了一套規范。

    對于Android 9.0也就是28,google推出了DisplayCutout,它統一了android凹凸屏的處理,使用起來也很方便。

    WindowManager.LayoutParams wlp = getWindow().getAttributes();
    wlp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
    getWindow().setAttributes(wlp);

    給WindowManager.LayoutParams設置layoutInDisplayCutoutMode就行,是不是很簡單。
    它有幾個參數可供選擇

    (1)LAYOUT_IN_DISPLAY_CUTOUT_MODE_DEFAULT:默認值,一般效果和LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER相同。

    (2)LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES:內容顯示到凹凸屏區域。

    (3)LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER:內容不會顯示到凹凸屏區域。

    對于Android 28以下的適配

    這個比較麻煩,因為在28以下是沒有layoutInDisplayCutoutMode的,所以要單獨去調,網上也有很多說如何去對不同的廠商去做適配,但其實這東西還是要調的。哪怕你是相同的機型,不同的系統版本都可能會產生不同的效果,沒錯,就是這么恐怖。基本都是只能做if-else單獨對不同的機型做適配。要么就是讓28以下的統一不做全面屏的效果,比如說把內容顯示到凹凸屏區域,你就判斷在28的時候不做這種操作,但一般不是你說的算,多多少少還是需要做適配,只能具體情況具體調試。

    對不同的場景做適配

    你覺得你說你就對28做適配,28以下就不管了,我就設置layoutInDisplayCutoutMode一行代碼就行。可事情哪有這么簡單。

    系統的Bar主要分為3種,一種是在屏幕上方的狀態欄,一種是在屏幕底端的導航欄,還是一直是仿IOS的底部橫條代替導航欄,這在和導航欄一起分析但會有些許不同。

    而這個過程中又會區分為橫屏和豎屏的情況,多少也會又些許差異,當然我也沒辦法把全部特殊的常見列舉出來。不同的手機廠商之間也會存在有不同的情況,還有上面說的android28前后,這里主要是對android28之后進行分析。

    狀態欄

    假如要實現全屏顯示的效果,我們要如何去對狀態欄做適配。

    為了方便調試,我把window的顏色設置為橙色,把布局的顏色設置成綠色

    <style name="TestTheme" parent="@android:style/Theme.Material.Light.NoActionBar.Fullscreen" >
        <item name="android:windowBackground">@android:color/holo_orange_light</item>
    </style>
    <activity
        android:name=".TestActivity"
        android:configChanges="orientation|screenSize|keyboardHidden|smallestScreenSize|screenSize|screenLayout"
        android:theme="@style/TestTheme" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#336655"
        >
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="用于參考位置"
            />
    </FrameLayout>

    然后我們直接運行看看效果

    Android全面屏適配怎么實現

    能看到,內容是不會顯示在狀態欄的空間的。根據上面提到的,我們用layoutInDisplayCutoutMode試試

    public class TestActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                WindowManager.LayoutParams wlp = getWindow().getAttributes();
                wlp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                getWindow().setAttributes(wlp);
            }
        }
    }

    看看效果

    Android全面屏適配怎么實現

    能看到狀態欄顯示橙色,這說明window的內容已經能覆蓋到狀態欄了,但是顯示的內容還是沒上去。

    難道這個屬性不行?當然不是。這個不知道怎么解釋好,你可以簡單理解成窗口是已經能顯示到狀態欄的區域了,但是view因為某些默認的配置導致距離頂部有一定的間距。

    相信大家多多少少聽過沉浸模式,我之前寫的軟鍵盤沖突也有涉及到一點這塊,view有一個方法SystemUiVisibility,它可以設置一些屬性,其實這是一個int值的flags,你把它想象成window的flags就好理解多了。

    通過setSystemUiVisibility方法,我們對View做一些配置,就按網上寫的,沉浸模式

    public class TestActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                WindowManager.LayoutParams wlp = getWindow().getAttributes();
                wlp.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
                getWindow().setAttributes(wlp);
                getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
            }
        }
    }

    看看效果

    Android全面屏適配怎么實現

    可以看到,內容就正常顯示到上面了。我覺得講得已經挺詳細了,好,那提兩個問題:如果我不設layoutInDisplayCutoutMode,只設View的SystemUiVisibility,能不能顯示到狀態欄的區域?第二個,我設了layoutInDisplayCutoutMode,是不是這個window里面的所有view都必須設置SystemUiVisibility才能把內容顯示到狀態欄區域?

    這個是實現一個把內容顯示到狀態欄的效果,還有其它效果比如設置狀態欄顏色或者什么的,這里就不講了,但要注意,如果你在設置某些效果的過程中,沒效果,可以考慮一下是不是手機廠商造成的,多試幾個廠商。

    對了,還有橫屏的情況,橫屏的情況下狀態欄還是在頂部,但是劉海區域(凹凸區域)在側邊,layoutInDisplayCutoutMode是對側邊的凹凸區域生效。所以要知道它不是針對狀態欄的,是針對凹凸區域的。

    導航欄和底部橫條

    這個就比狀態欄麻煩一些。這里就主要以橫屏的情況去講解。橫屏的情況下導航欄一共有3種顯示情況,例如小米的橫條,就是顯示在底部,其它手機的導航欄就是顯示在側邊,還有一種是側邊的情況下,不管你怎么轉屏,都會固定顯示在右邊。

    導航欄沒有凹凸區域,所以不需要用到windoow lp的layoutInDisplayCutoutMode,我們一般都能直接通過view的SystemUiVisibility方法去配置實現它的一個想要的效果。

    可以先看看SystemUiVisibility能設置的一些常用的flags

    public static final int SYSTEM_UI_FLAG_VISIBLE = 0; // 系統UI(狀態欄導航欄)顯示
    public static final int SYSTEM_UI_FLAG_LOW_PROFILE = 0x00000001; // 低調模式(就是類似于變暗等效果)
    public static final int SYSTEM_UI_FLAG_HIDE_NAVIGATION = 0x00000002; // 隱藏導航欄和橫條
    public static final int SYSTEM_UI_FLAG_FULLSCREEN = 0x00000004; // 全屏模式,系統UI會被隱藏
    public static final int SYSTEM_UI_FLAG_LAYOUT_STABLE = 0x00000100; // 穩定布局
    public static final int SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION = 0x00000200; // 對窗口生效SYSTEM_UI_FLAG_HIDE_NAVIGATION
    public static final int SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN = 0x00000400; // 對窗口生效SYSTEM_UI_FLAG_FULLSCREEN
    public static final int SYSTEM_UI_FLAG_IMMERSIVE = 0x00000800; // 讓SYSTEM_UI_FLAG_HIDE_NAVIGATION失效
    public static final int SYSTEM_UI_FLAG_IMMERSIVE_STICKY = 0x00001000; // 同上相反

    關于SYSTEM_UI_FLAG_LAYOUT_STABLE穩定布局,官方有一段注釋是這么說的,如果指定SYSTEM_UI_FLAG_LAYOUT_FULLSEEN和SYSTEM_UI-FLAG_LAYOUT _HIDE_NAVIGATION,則可以使用穩定的布局轉換到SYSTEM_UI_FLAG_FULLSCREEN和SYSTEM _UI_FLAG-HIDE_NAVIGATION。(請注意,應避免單獨使用SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION。)如果已將窗口標志WindowManager.LayoutParams.FLAG_FULLSCREEN設置為隱藏狀態欄(而不是使用SYSTEM.UI_FLAG_FULLSCREEN),則隱藏的狀態欄將被視為“穩定”狀態。

    這什么意思呢?意思就是這個屬性不是死的,它會受其它東西影響到最終的顯示效果。說人話就是你用它的話實現的效果就很靈活,但同樣會出BUG的概率也更高。

    關于SYSTEM_UI_FLAG_IMMERSIVE讓SYSTEM_UI_FLAG_HIDE_NAVIGATION失效,官方有一段注釋是這么說的:由于此標志是SYSTEM_UI_FLAG_HIDE_NAVIGATION的修飾符,因此僅當與該標志結合使用時才具有效果。它所表現出來的效果是SYSTEM_UI_FLAG_HIDE_NAVIGATION會隱藏導航欄,但當你手動拉出導航欄之后,就不會再隱藏了。

    但這也涉及到不同的手機廠商可能會出現不同的效果。比如小米,默認的顯示會是這樣

    Android全面屏適配怎么實現

    可以看出,橫條是顯示在底部,側邊沒有導航欄,然后我們一個一個flags來調看看效果。首先SYSTEM_UI_FLAG_LAYOUT_STABLE這種情況我是不調了,很難去模擬出來。SYSTEM_UI_FLAG_VISIBLE和SYSTEM_UI_FLAG_LOW_PROFILE效果在這里顯示的應該會和默認情況顯示的一樣。

    這里我會模擬兩種場景來說,第一種是純activity的window的view設置的效果,第二種是window.addview的view設置的效果(我后續會稱之為兩層window),它們的效果會有些許差異

    1. SYSTEM_UI_FLAG_HIDE_NAVIGATION

    先看看SYSTEM_UI_FLAG_HIDE_NAVIGATION,假如我設置了SYSTEM_UI_FLAG_HIDE_NAVIGATION

    getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);

    Android全面屏適配怎么實現

    可以看到,底部橫條已經不顯示了。這里可以多說一句,你們猜猜SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION對view管不管用,可以試試

    只設置它能明顯看出底部的橫條還是存在的。\但是當用window.addview之后再配置SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION的話,可以看看效果。
    代碼是這樣的

    public class TestActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
            addWindow();
        }
        private void addWindow() {
            WindowManager wm = getWindowManager();
            WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
            wlp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.gravity = Gravity.START | Gravity.TOP;
            TextView textView = new TextView(this);
            textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setText("上一層");
            textView.setBackgroundResource(R.color.blue);
            wm.addView(textView, wlp);
        }
    }

    看看效果,看到差異沒有,我們之前設置的話,它的橫條還在,并且是黑色的,現在有一個window然后我們設置之后發現橫條還在,但背景變成透明的了。

    Android全面屏適配怎么實現

    2. SYSTEM_UI_FLAG_FULLSCREEN

    看看單獨設置SYSTEM_UI_FLAG_FULLSCREEN的效果

    Android全面屏適配怎么實現

    看得到效果也是一樣的。說明SYSTEM_UI_FLAG_FULLSCREEN是不會隱藏底部導航欄的。

    但這個屬性是不是就沒用了,并不是,假如我使用兩層window的的情況,不設置這個參數的話,可以看到效果會是這樣的:狀態欄拉下來不會停留,會快速的縮回去

    但如果我設置了,代碼寫成這樣

    public class TestActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test); 
            addWindow();
        }
        private void addWindow() {
            WindowManager wm = getWindowManager();
            WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
            wlp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.gravity = Gravity.START | Gravity.TOP;
            TextView textView = new TextView(this);
            textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setText("上一層");
            textView.setBackgroundResource(R.color.blue);
            wm.addView(textView, wlp);
            textView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);
        }
    }

    能看到效果狀態欄下拉后就能正常的短暫停留才消失

    3. SYSTEM_UI_FLAG_IMMERSIVE_STICKY

    前面說了SYSTEM_UI_FLAG_IMMERSIVE_STICKY是配合SYSTEM_UI_FLAG_HIDE_NAVIGATION的,所以我們這里測試的時候,寫SYSTEM_UI_FLAG_HIDE_NAVIGATION。

    直接是單層window去設置的話是看不出明顯效果的,比如代碼這樣

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    //        addWindow();
        }

    我把第二層給注釋掉,然后給第一層設置SYSTEM_UI_FLAG_HIDE_NAVIGATION,不管設不設置SYSTEM_UI_FLAG_IMMERSIVE_STICKY,它在我這臺手機,表現都一樣。我強調“我這臺手機”,是因為可能會不同機型有不同的表現。

    然后我們用兩層去做看看效果,代碼這樣

    public class TestActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            addWindow();
        }
        private void addWindow() {
            WindowManager wm = getWindowManager();
            WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
            wlp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.gravity = Gravity.START | Gravity.TOP;
            TextView textView = new TextView(this);
            textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setText("上一層");
            textView.setBackgroundResource(R.color.blue);
            wm.addView(textView, wlp);
            textView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
        }
    }

    不設置SYSTEM_UI_FLAG_IMMERSIVE_STICKY的情況下,我這里沒辦法錄gif(因為點了就會影響),它的效果是,一開始底部橫條是隱藏的,但是當點擊之后會顯示并且顯示之后就不再隱藏。

    設置之后

    public class TestActivity extends Activity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            addWindow();
        }
        private void addWindow() {
            WindowManager wm = getWindowManager();
            WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
            wlp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
            wlp.gravity = Gravity.START | Gravity.TOP;
            TextView textView = new TextView(this);
            textView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setText("上一層");
            textView.setBackgroundResource(R.color.blue);
            wm.addView(textView, wlp);
            textView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
        }
    }

    看到底部橫條會變透明,然后拉出來一段時間之后會自己隱藏起來。PS:看到這里狀態欄縮回去很快,是因為沒設置SYSTEM_UI_FLAG_FULLSCREEN

    SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

    SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN的效果是什么的?

    這里我就補貼代碼直接讓你們看看現象吧,如果不設置的話,window會被位移(或者說擠壓)再恢復。但如果設置的話就不會有這種問題。

    以上就是“Android全面屏適配怎么實現”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    剑河县| 锦屏县| 五河县| 安仁县| 饶河县| 大田县| 巫山县| 崇阳县| 巴南区| 郸城县| 宜城市| 塔河县| 根河市| 涿鹿县| 庆城县| 西平县| 隆德县| 大冶市| 洛浦县| 萝北县| 邵东县| 哈巴河县| 乐清市| 岚皋县| 土默特左旗| 永定县| 三亚市| 灵石县| 龙井市| 阳朔县| 卫辉市| 来凤县| 莲花县| 应城市| 永春县| 连云港市| 通河县| 锡林浩特市| 肥东县| 穆棱市| 当雄县|