編輯:關於Android編程
本文以學習、研究和分享為主,歡迎轉載,但必須在文章頁面明顯位置給出原文連接。願與志同道合的朋友一起成長
在上一個博文 Anroid沉浸式狀態欄中提到了,畫了一個圖,這個圖簡單將我們的狀態欄分為不同的2個維度來看狀態欄。其中涉及的概念我不在贅訴,請返到Anroid沉浸式狀態欄再去認識下這幾個概念。下文中提到的上節就是Anroid沉浸式狀態欄。
由於上一講提到了基本的實現方法和一些可能會用到的方法,但是沒有實際操作和演示,那我們現在就來一步步來去實現我們提到的三種狀態欄的實現過程。
全屏模式下的透明狀態欄,實現的app其實我們肯定見過,如我們的啟動頁很多情況下就是全屏模式,但是這個還是和我們說的不太一樣,不過今天我們介紹的這個是狀態欄透明,但是仍然存在。
網易新聞這種才是真正的浸入式狀態欄:
但是不是我們需要的效果,這種是全屏模式時,當前頁面獲取焦點就顯示一個有一定透明度的暗色狀態欄。
我們希望的是小米天氣的這種:
內容部分可以延伸到狀態欄,且狀態欄是透明的,無背景色,也就是我們的全屏模式。
按照我們上節拿來實踐下。
public static void setFullSreen(Activity activity){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 設置透明狀態欄,這樣才能讓 ContentView 向上 activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } }
我將一個圖片鋪滿contentView。
這個截圖是在4.4上完成的。
但是在6.0上的效果還差強人意:
這個是在我的N5手機上跑的,上面有灰色的陰影。不是完全透明,和我們的小氣天氣不太一樣,好了還是用到上節的方法:
public static void setFullSreen(Activity activity){ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { Window window = activity.getWindow(); window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN| View.SYSTEM_UI_FLAG_LAYOUT_STABLE); window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS); window.setStatusBarColor(Color.TRANSPARENT); }else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // 設置透明狀態欄,這樣才能讓 ContentView 向上 activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); } }
這樣就可以使得狀態欄也透明了。
可能有些人會迷惑,為什麼我們要設置彩色狀態欄,在5.0可以直接設置主題來設置的,我要告訴你的是我們希望4.4上也有彩色的狀態欄。上節我們提到了彩色狀態欄的實現方法:就是先設置為屏幕模式下的透明狀態欄,再在透明狀態欄的垂直下方放置一個和狀態欄同樣高寬的view,我們操作他這個空白view的顏色,即可實現彩色狀態欄。
好了我們貼出來我們的代碼邏輯吧:
/** *設置彩色的狀態欄 * * @param activity * @param color 狀態欄需要設置的背景顏色 * @param statusBarAlpha 狀態欄需要設置的背景顏色的透明度 */ public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha){ //先設置的全屏模式 setFullSreen(activity); //在透明狀態欄的垂直下方放置一個和狀態欄同樣高寬的view addStatusBarBehind(activity,color,statusBarAlpha); } /** * 添加了一個狀態欄(實際上是個view),放在了狀態欄的垂直下方 */ public static void addStatusBarBehind(Activity activity, @ColorInt int color, int statusBarAlpha) { //獲取windowphone下的decorView ViewGroup decorView = (ViewGroup) activity.getWindow().getDecorView(); int count = decorView.getChildCount(); //判斷是否已經添加了statusBarView if (count > 0 && decorView.getChildAt(count - 1) instanceof StatusBarView) { decorView.getChildAt(count - 1).setBackgroundColor(calculateStatusColor(color, statusBarAlpha)); } else { //新建一個和狀態欄高寬的view StatusBarView statusView = createStatusBarView(activity, color, statusBarAlpha); decorView.addView(statusView); } setRootView(activity); } /** * 設置根布局參數 */ private static void setRootView(Activity activity) { ViewGroup rootView = (ViewGroup) ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0); //rootview不會為狀態欄流出狀態欄空間 ViewCompat.setFitsSystemWindows(rootView,false); rootView.setClipToPadding(true); } private static StatusBarView createStatusBarView(Activity activity, int color, int alpha) { // 繪制一個和狀態欄一樣高的矩形 StatusBarView statusBarView = new StatusBarView(activity); LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)); statusBarView.setLayoutParams(params); statusBarView.setBackgroundColor(calculateStatusColor(color, alpha)); return statusBarView; } /** * 獲取狀態欄高度 * * @param context context * @return 狀態欄高度 */ private static int getStatusBarHeight(Context context) { // 獲得狀態欄高度 int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(resourceId); } /** * 計算狀態欄顏色 * * @param color color值 * @param alpha alpha值 * @return 最終的狀態欄顏色 */ private static int calculateStatusColor(int color, int alpha) { float a = 1 - alpha / 255f; int red = color >> 16 & 0xff; int green = color >> 8 & 0xff; int blue = color & 0xff; red = (int) (red * a + 0.5); green = (int) (green * a + 0.5); blue = (int) (blue * a + 0.5); return 0xff << 24 | red << 16 | green << 8 | blue; }
其中狀態欄的view就是一個簡單的view,貼出來的這個類吧:
public class StatusBarView extends View { public StatusBarView(Context context, AttributeSet attrs,int style) { super(context, attrs,style); } public StatusBarView(Context context, AttributeSet attrs) { super(context, attrs); } public StatusBarView(Context context) { super(context); } }
搞定,我們就可以來動態改變狀態欄的顏色了。
calculateStatusColor 方法中的alpha是0-255的,0的時候其實是不透明的,當設置255相當於statusview背景透明,即為默認色黑色。
可用的函數是public static void setColor(Activity activity, @ColorInt int color, int statusBarAlpha)和
setFullSreen
小結
Now現在這個工具類就算是OK,對於代碼的侵入基本上為零,直接拿來當工具類,不用改主題,簡單易容用。也為大家提供一個思路,這個只是實現的基本功能,一些復雜的定制的情況,可以隨機應變,自由組合使用。
實現狀態欄,無非是將4.4-5.0 和5.0+的分別實現,當然配合decorview和 ViewCompat.setFitsSystemWindows(view,boolean)使用效果更佳。
1、事務2、命令行操作數據庫
anddroid studio的內存修改昨天有位朋友問到了下面的一個問題這個判斷為android studio的分配的內存不夠用。據我的了解造成這個的原因主要有以下幾個方
微信6.0主界面:(1)整體采用垂直的LinearLayout線性布局(2)最上面是ActionBar,搜索框SearchView,Overflow(含有4個單選菜單項)
這篇文章寫的非常好,深入淺出,關鍵還是一位大三學生自己剖析的心得。這是我喜歡此文的原因。下面請看正文:作為一個大三的預備程序員,我學習android的一大樂趣是可以通過源
本文介紹本文是翻譯自Google 官方課程 Building Apps