Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 實現Android K的假裝沉浸式,android假裝沉浸

實現Android K的假裝沉浸式,android假裝沉浸

編輯:關於android開發

實現Android K的假裝沉浸式,android假裝沉浸


在Android 5.0之後引入了MD風格,並且狀態欄沉浸也成為了一種設計習慣。而停留在之Android L之前的Android系統則不能直接實現沉浸式,這裡就介紹一下如何實現Android K系列的假裝沉浸式。

關於沉浸式效果,這裡隨便貼幾張圖吧

 

              Android L效果圖

 

               Android 4.2效果圖

 

可以看出在Android K系列中,狀態欄是漸變的效果

下面開始講解如何實現上圖的效果,在此就不贅述Android L或以上的沉浸式的效果實現了,在xml上配置幾個屬性就可以了

 

題外話:這篇文章介紹的都是使用Android Studio作為IDE開發Android的,如果使用的是其他IDE應按照相關設置進行設置或者配置xml等文件。

 

開始學習假裝沉浸式

所謂的其他知識,就是創建一個其他App中的Activity共有的基類BaseActivity,讓其繼承AppCompatActivity,然後在基類中實現假裝沉浸式,這樣Acticity就能專注於自己的內容,而把這些共有的設置交給BaseActivity處理。

現在看看這部分如何處理,先看代碼:

 1 public class  BaseActivity extends AppCompatActivity {
 2 
 3     private int mColor;
 4     
 5     public BaseActivity(){
 6     }
 7 
 8     public BaseActivity(int color){
 9         super();
10         mColor = color;
11     }
12 
13     @Override
14     protected void onCreate(@Nullable Bundle savedInstanceState) {
15         super.onCreate(savedInstanceState );
16         StatusBarCompat.compat(this, ContextCompat.getColor(this, mColor));
17     }
18 
19     public static class StatusBarCompat{
20 
21         private static final int INVALID_VAL = -1;
22         private static final int COLOR_DEFAULT = Color.parseColor("#20000000");
23 
24         public static  void compat(Activity activity, int statusColor){
25             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
26                 if(statusColor != INVALID_VAL){
27                     activity.getWindow().setStatusBarColor(statusColor);
28                 }
29                 return;
30             }
31 
32             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
33                     && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP){
34                 int color = COLOR_DEFAULT;
35                 ViewGroup contentView = (ViewGroup) activity.findViewById(android.R.id.content);
36 
37                 if(statusColor != INVALID_VAL){
38                     color = statusColor;
39                 }
40 
41                 View statusBarView = new View(activity);
42                 ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
43                         getStatusBarHeight(activity));
44                 statusBarView.setBackgroundColor(color);
45 
46                 contentView.addView(statusBarView, lp);
47                 //contentView.addView(statusBarView, 0, lp);
48             }
49         }
50 
51         public static void compat(Activity activity){
52             compat(activity, INVALID_VAL);
53         }
54 
55         public static int getStatusBarHeight(Context context){
56             int result = 0;
57 
58             int resourceId = context.getResources().getIdentifier("status_bar_height",
59                     "dimen", "android");
60 
61             if(resourceId > 0){
62                 result = context.getResources().getDimensionPixelSize(resourceId);
63             }
64 
65             return result;
66         }
67     }
68 }

 

跟著步驟,沒必要全部看那些凌亂的代碼,在這裡講解重點部分,在BaseActivity中提供了一個單一參數的構造函數,目的是讓子類選擇假裝沉浸的顏色,在onCreate函數中調用了StatusBarCompat.compat(this, ContextCompat.getColor(this, mColor))函數,StatusBarCompat是其內部類,我們看看compat函數是如何實現假裝沉浸的。

 

第一個if是判斷系統如果為Android L或以上的系統則直接調用setStatusBarColor函數,這是API 21之後提供設置狀態欄顏色的函數,然後是第二個if用於判斷是否為Android K系統,如果是則開始我們的步驟。裡面的內容其實是這樣的,我們在XML裡配置好狀態欄的背景為透明,然後在我們的布局中插入一個和狀態欄等高的View,從而在視覺上看起來就是沉浸式的效果了。從字面上很容易理解這樣做的意義,然後簡單分析一下可行性。首先,如何獲取我們的布局,方法很多,可以給根布局設置一個id,然後Activity.findViewById直接獲取根布局。其實在這裡也可以不獲取布局,可以在xml中設置一個View,然後在這裡獲取這個View並且設置它的高度為狀態欄的高度,背景為Activity中傳過來的顏色即可。這裡就不介紹這兩種方法,介紹一種獲取我們根布局的其他方法。代碼35行findViewById(android.R.id.content)獲取了一個FrameLayout,然後奇怪了,為什麼是獲取一個FrameLayout呢,其實是這樣的,我們的布局都是設置在AppCompatActivity的FrameLayout布局中的,這段代碼就是為了獲取這個ViewGroup的內容的,因此,現在我們手中就掌握了整個Activity的ViewGroup,我們的操作就在這裡進行。獲取了真正的根布局,當然是開始創建一個View,然後讓其高度和狀態欄高度一致,然後再設置到剛剛獲取的ViewGroup中去就可以了。其中getStatusBarHeight就是獲取系統狀態欄高度的函數,然後設置View的背景色,然後add到ViewGroup就完成了整個操作。現在工作還沒完成呢,既然是Android K的機子,先配置XML吧,在res目錄下新建一個values-v19的文件夾,然後新建styles.xml文件,貼上以下代碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3     <style name="AppTheme" parent="@style/BaseAppTheme">
4         <item name="android:windowTranslucentStatus">true</item>
5     </style>
6 </resources>

順便看看BaseAppTheme的代碼,這部分代碼在res/values/styles裡面:

1 <style name="BaseAppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
2         <!-- Customize your theme here. -->
3         <item name="colorPrimary">@color/colorPrimary</item>
4         <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
5         <item name="colorAccent">@color/colorAccent</item>
6 </style>

其中android:windowTranslucentStatus屬性設置的是狀態欄是否設置為透明狀態,這個是v19之後才引入的屬性。

到這裡,看似好像完成了,但問題還沒完全解決,那就是ToolBar的空間位置問題,假如不處理,如圖:

看出效果是ToolBar和狀態欄擠成了一塊,但這不是這篇文章中所想要的效果,那應該怎麼辦呢?其實只需設置ToolBar的一個屬性android:fitsSystemWindows="true"即可。該屬性的意義就是讓當前設置這個屬性的view設置對應的padding為狀態欄騰出對應的空間,說白了就好像是paddingTop=statusHeight。

按步驟設置好之後,還有一步,不然看到的是代碼裡面默認設置的顏色,所以要在Activity中傳遞color給BaseActivity,簡單的代碼如下:

1 public MainActivity(){
2     this(R.color.colorPrimary);
3 }
4 
5 private MainActivity(int color){
6     super(color);
7 }

只需修改R.color.colorPrimary為自己需要的顏色即可。為什麼需要這樣操作,很簡單,因為默認啟動調用的是無參構造函數,所以讓無參去調用有參構造,即可實現,這也解釋了為什麼父類要去定義這個有參構造了。

 

運行了一下效果,嗯,還不錯,但當你如果用的是這個方法添加的view作狀態欄背景色的話,其實有一個坑,不過我貼的代碼上已經解釋了這個坑的處理方法了。這個坑其實就是和DrawerLayout配合使用的時候,當你打開抽屜的時候,會看到側滑菜單在狀態欄的下面,如圖所示:

可以看到,狀態欄把側滑菜單擋住了,說白了其實是我們添加的view把狀態欄擋住了。如何解決呢,在上面代碼中注釋了一句,其實使用下面那個三參數的函數就可以解決這個問題了,如圖:

可以看出,側滑菜單已經覆蓋在假裝狀態欄的那個view上面了。為什麼會這樣呢,理由很簡單,使用第一個函數的時候它是直接add到FrameLayout最上面的,所以就擋在了我們的布局上面,而addView(statusBar, 0, lp)的意思則是插入到第1個View的位置,因此就會讓它插入到我們的布局下面,因此就實現了我們所想要的效果。既然兩個參數有先後問題,那我們是否可以在Activity的onCreat函數中這樣操作呢,比如先super.onCreat然後再調用setContentView,看似這樣子我們的布局就應該在假裝狀態欄背景的view上面了,其實這是一個坑,我們在onCreat中必須是先調用setContentView然後再調用基類的onCreat,否則,狀態欄的效果如圖:

其實,從setContentView的名字可以看出來為什麼了,既然這個是設置自定義布局,顯然,調用這個函數的時候會將FrameLayout裡面的內容清空,因此後調用這個函數的時候,之前add

進去的view已經被清空了。

 

到這裡,關於Android K的假裝沉浸式效果就實現了。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved