亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

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

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

透明系統欄及沉浸模式的總結

發布時間:2020-09-01 18:41:04 來源:網絡 閱讀:3318 作者:一劍圍城 欄目:移動開發

關于所謂的“沉浸式”,我有許多話要說,因為這個東西實在是折磨了我許多的時間。實現的方式有許多,兼容性問題也不少。官方文檔也讓我感到也有些云里霧里。那些“長得很相似”的Flag,適用情況很接近的設置方法,讓我不得不一個個測試,然而卻一次次推翻。模擬器上測試;真機上測試;4.4版本上的測試;5.0后版本的測試;有導航欄手機上的測試;老掉牙手機上的測試。總而言之,這個東西的探索讓我深刻地體會到android系統兼容性問題的麻煩。

當你功能開發占據10%,而處理兼容性問題占據90%的時候。你不得不思考這樣一個問題:“兼容性真的有那么重要嗎?”撇開這個問題,以投入和產出的角度顯然是不太劃得來的,但是收獲的角度:我學習了解了View的加載機制、DecorView在不同版本上的實現以及發展、養成了遇到問題第一時間查閱官方文檔的習慣。

 

關鍵詞

1、系統欄Systembar(包括狀態欄Statusbar,導航欄Navigationbar)

2、內容主體暫且可以理解為Window中除了Systembar以外的窗口

 

實現原理:

1、將SystemBar透明化

2、根據不同情況決定內容主體是否需要延伸到SystemBar下方

 

一、將SystemBar透明化

主題中設置屬性:

<itemname="android:windowTranslucentStatus">true</item>

<itemname="android:windowTranslucentNavigation">true</item>


代碼中設置Flag:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);//透明狀態欄

getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);//透明導航欄


5.0后設置:

     getWindow().setStatusBarColor(Color.TRANSPARENT);

     getWindow().setNavigationBarColor(Color.TRANSPARENT);

 

二、根據不同情況決定內容主體是否需要延伸到SystemBar下

主題中設置屬性:

      <itemname="android:windowFullscreen">true</item>

代碼中設置Flag:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

FLAG_TRANSLUCENT_STATUS單獨使狀態欄透明化

FLAG_TRANSLUCENT_NAVIGATION單獨使導航欄透明化

4.1后更多選項的設置:

ViewdecorView = getWindow().getDecorView();

decorView.setSystemUiVisibility(Flag);

Flag的值需要了解以下幾種情況:

1、SYSTEM_UI_FLAG_FULLSCREEN

2、SYSTEM_UI_FLAG_HIDE_NAVIGATION

3、SYSTEM_UI_FLAG_IMMERSIVE

4、SYSTEM_UI_FLAG_IMMERSIVE_STICKY

5、SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

6、SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

7、SYSTEM_UI_FLAG_LAYOUT_STABLE

8、SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

 

SYSTEM_UI_FLAG_FULLSCREEN

隱藏狀態欄,主體向上偏移,但在手動下拉會重新顯示狀態欄并清除該flag。

View.SYSTEM_UI_FLAG_FULLSCREEN |View.SYSTEM_UI_FLAG_LAYOUT_STABLE

限制主體位置保持不變,狀態欄留白

 

SYSTEM_UI_FLAG_HIDE_NAVIGATION

隱藏導航欄,主體向下偏移,由于導航欄太重要了,所以只要和Activity進行任何交互都會重新顯示導航欄,并清除該flag和SYSTEM_UI_FLAG_FULLSCREEN。

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_LAYOUT_STABLE

限制主體位置保持不變,導航欄留白

 

SYSTEM_UI_FLAG_LAYOUT_STABLE

保持內容主體位置不變,不隨著Systembar的隱藏顯示而偏移

 

SYSTEM_UI_FLAG_IMMERSIVE

沉浸模式:只能和SYSTEM_UI_FLAG_HIDE_NAVIGATION結合使用。簡單交互不會重新顯示導航欄

 

SYSTEM_UI_FLAG_IMMERSIVE_STICKY

沉浸模式:只能和SYSTEM_UI_FLAG_FULLSCREEN或SYSTEM_UI_FLAG_HIDE_NAVIGATION結合使用。

下拉狀態欄位置可以短暫顯示狀態欄和導航欄,然后再次隱藏。

 

SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

主體占據全部屏幕,但不隱藏狀態欄,這里的layout可以理解為內容主體

 

SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION

主體占據全部屏幕,但不隱藏導航欄,這里的layout可以理解為內容主體

 

SYSTEM_UI_FLAG_LAYOUT_STABLE

這個Flag確實有點難以理解,唯一讀懂的是在各種flag切換的時候能保持內容主體的穩定性。如果你不想flag變換的時候內容主體上下偏移,就需要設置SYSTEM_UI_FLAG_LAYOUT_STABLE。

 

View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR

淺色狀態欄模式:對應于圖標變深色,防止淺色背景導致狀態欄看不清,不設置是深色模式

 

實踐驗證過程:

View decorView =getWindow().getDecorView();

decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

狀態欄不會隱藏,仍占據著位置,但內容可以侵入狀態欄下方

 

decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_FULLSCREEN);

View.SYSTEM_UI_FLAG_FULLSCREEN 狀態欄下滑,主體布局就會下降一個狀態欄的高度,很突兀

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN狀態欄下滑,主體布局位置不變化

 

View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;

這個和單獨使用View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN區別在哪兒,還沒發現

 

andriod系統提供了一些透明狀態欄/導航欄的主題以供使用:

<stylename="Theme.Material.Light.NoActionBar.TranslucentDecor">

    <item name="windowTranslucentStatus">true</item>

    <itemname="windowTranslucentNavigation">true</item>

    <itemname="windowContentOverlay">@null</item>

</style>

 

SYSTEM_UI_FLAG_HIDE_NAVIGATION |SYSTEM_UI_FLAG_IMMERSIVE

SYSTEM_UI_FLAG_IMMERSIVE必須與SYSTEM_UI_FLAG_HIDE_NAVIGATION 結合使用才有意義

加上SYSTEM_UI_FLAG_IMMERSIVE,則導航欄在隱藏后不會因與界面的交互而呼出。

類似于看視頻時進入全屏模式。

 

SYSTEM_UI_FLAG_FULLSCREEN |SYSTEM_UI_FLAG_HIDE_NAVIGATION

進入全屏模式,但用戶與界面進行最簡單的交互都會重新顯示狀態欄,導航欄

 

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION|View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE

進入全屏模式,用戶交互會重新顯示狀態欄,導航欄,不會再隱藏

 

View.SYSTEM_UI_FLAG_HIDE_NAVIGATION| View.SYSTEM_UI_FLAG_FULLSCREEN | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY

進入全屏模式,用戶交互會短暫顯示狀態欄,導航欄,然后再隱藏

 

總結:

比較簡潔的透明狀態欄的做法是:

方法一:適合4.1及以上

if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){

    View window =getWindow().getDecorView();

    window.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN

           |View.SYSTEM_UI_FLAG_LAYOUT_STABLE);

    getWindow().setStatusBarColor(Color.TRANSPARENT);

}

對于不需要延伸至狀態欄下方的組件,使用android:fitsSystemWindows="true"將進行設置即可。本質上是添加一個狀態欄高度的paddingTop屬性,所以android:layout_height屬性不要使用"250dp"這種固定數值,可以使用"wrap_content"結合android:minHeight="250dp"的方式。

 

方法二:適合4.1及以上

同方法一:

<itemname="android:windowTranslucentStatus">true</item>

      <itemname="android:windowTranslucentNavigation">true</item>

結合android:fitsSystemWindows屬性

 

方法三:適合4.0及以下的版本

<itemname="android:windowFullscreen">true</item>

      <itemname="android:windowContentOverlay">@null</item>

或者代碼中:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);

方法三使用android:fitsSystemWindows是無效的。所以我的做法是給需要向下偏移的組件設置一個paddingTop的值,并在v21,v19等不同版本設置不同的值做兼容(源碼可知statusbar高度是25dp)。這里默認所有手機平臺都是25dp。

網上的做法是選擇性填充一個View,該View的Height是動態獲取的statusbar的高度。這個做法兼容了不同廠商自己定制的UI使用不同于Google官方25dp的狀態欄高度的情況。如紅米note2是20dp,魅族note5是22dp。

 

另外對于setFlags方法,同樣有單獨設置狀態欄和導航欄的方法:

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION,WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    對于這兩個屬性而言,android:fitsSystemWindows有效,但在設置了FLAG_TRANSLUCENT_NAVIGATION的時候,內容主體也會向下偏移一個導航欄的高度,可見這里的android:fitsSystemWindows指的是SystemBar,而不僅僅是StatusBar。


方法四:適合于5.0以后

結合Design Support庫中的CoordinatorLayout+AppBarLayout+CollapsingToolbarLayout,并且結合使用fitsSystemWindows。這也是我第一個接觸的方法。需要注意的是fitsSystemWindows屬性在CoordinatorLayout中有不同的實現,fitsSystemWindows=“true”反而表示是否出現在狀態欄下方。知道真相的我眼淚掉下來。

方法在Fragment中會有問題(例如在FragmentTabhost中使用),使用replace切換則正常,使用add切換的Fragment則fitSystemWindow失效,必須調用onCreate才能生效,我滴個天~~~~最后我只能放棄fitSystemWindow,使用方法三中的設置paddingTop的方法。


方法五:使用第三方框架

SystemBarTint      https://github.com/jgilfelt/SystemBarTint

StatusBarUtil        https://github.com/laobie/StatusBarUtil

 

備注:

使用Theme的方式相比代碼中設置的優勢:

1、更易于維護,并且不易出錯

2、更順暢的UI過渡,因為系統在初始化主Activity之前就已經知道了渲染UI所需要的相關信息

 

參考資料:

Managing the System UI

https://developer.android.com/training/system-ui/index.html

SystemBarTint

https://github.com/jgilfelt/SystemBarTint

StatusBarUtil

https://github.com/laobie/StatusBarUtil


向AI問一下細節

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

AI

安平县| 永平县| 凌云县| 南阳市| 凤山县| 玉门市| 德昌县| 东乌珠穆沁旗| 杭锦旗| 偏关县| 汉寿县| 调兵山市| 大邑县| 探索| 漳浦县| 三原县| 长春市| 浦东新区| 治多县| 天镇县| 芜湖县| 广东省| 宁乡县| 陆川县| 东明县| 八宿县| 腾冲县| 昆明市| 罗江县| 颍上县| 克山县| 刚察县| 潮州市| 二连浩特市| 磴口县| 延长县| 遂昌县| 额尔古纳市| 高邑县| 蕲春县| 南开区|