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

來源:互聯網
上載者:User

實現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     @Override14     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.KITKAT33                     && 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的假裝沈浸式效果就實現了。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.