編輯:關於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)使用效果更佳。
android 數據庫事務
1、事務2、命令行操作數據庫
我的android學習經歷38
anddroid studio的內存修改昨天有位朋友問到了下面的一個問題這個判斷為android studio的分配的內存不夠用。據我的了解造成這個的原因主要有以下幾個方
Android微信界面的設計
微信6.0主界面:(1)整體采用垂直的LinearLayout線性布局(2)最上面是ActionBar,搜索框SearchView,Overflow(含有4個單選菜單項)
android的消息處理機制(圖文+源碼分析)—Looper/Handler/Message
這篇文章寫的非常好,深入淺出,關鍵還是一位大三學生自己剖析的心得。這是我喜歡此文的原因。下面請看正文:作為一個大三的預備程序員,我學習android的一大樂趣是可以通過源
跟Google 學代碼 : Building Apps with Connectivity & the Cloud【Webapp Usage】
本文介紹本文是翻譯自Google 官方課程 Building Apps