安卓透明StatusBar及設置文字圖標顏色

自定義狀態(tài)欄的實現(xiàn)一般分為兩種方式:
1)將布局內容延展至狀態(tài)欄;
2)使用沉浸式狀態(tài)欄
斟珊。

由于大部分android系統(tǒng)狀態(tài)欄采用黑色背景浮毯,白色的字體圖標。這導致以上兩種實現(xiàn)方式存在一個共性問題舀瓢,即狀態(tài)欄背景顏色定義為白色等淺色調時,這導致狀態(tài)欄顯示白屏耗美。

該問題只能通過更改狀態(tài)欄字體圖標的顏色來解決京髓,但存在兼容性問題。目前只有MIUI6及以上商架、魅族以及android 6.0以上可以設置堰怨。

注意,測試手機MX5蛇摸,android系統(tǒng)5.1备图,flyme6.0.2.0A,在設置狀態(tài)欄顏色setStatusBar后皇型,系統(tǒng)會根據(jù)statusbar的色調自動變更狀態(tài)欄字體圖標顏色诬烹。

一、布局內容延展至狀態(tài)欄

注意:android 4.4及以上可以實現(xiàn)該功能弃鸦。

實現(xiàn)該功能最簡單粗暴的方法是使用屬性windowTranslucentStatus="true"绞吁,該屬性使布局內容得以延伸到狀態(tài)欄和導航欄所在的空間,形成類似全屏的視覺效果唬格。但使用該方法后會引入一些問題家破。

該屬性的java設置方法為:

activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS );
activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS );
1、界面布局上部分和狀態(tài)欄重合购岗。

該問題的解決方案:
1) 界面根布局設置屬性fitsSystemWindow=true汰聋,該屬性使得屏幕上的可布局空間位于狀態(tài)欄下方與導航欄上方。但該屬性只對簡單布局有效喊积,且可能引入EditText輸入時軟鍵盤遮擋光標的問題烹困;

一個高票workround解決方案如下:

//調用方式
//To use this class, simply invoke assistActivity() on an Activity that already has its content view set. 

//實現(xiàn)方法
public class AndroidBug5497Workaround {

    // For more information, see https://code.google.com/p/android/issues/detail?id=5497
    // To use this class, simply invoke assistActivity() on an Activity that already has its content view set.

    public static void assistActivity (Activity activity) {
        new AndroidBug5497Workaround(activity);
    }

    private View mChildOfContent;
    private int usableHeightPrevious;
    private FrameLayout.LayoutParams frameLayoutParams;

    private AndroidBug5497Workaround(Activity activity) {
        FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
        mChildOfContent = content.getChildAt(0);
        mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            public void onGlobalLayout() {
                possiblyResizeChildOfContent();
            }
        });
        frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
    }

    private void possiblyResizeChildOfContent() {
        int usableHeightNow = computeUsableHeight();
        if (usableHeightNow != usableHeightPrevious) {
            int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
            int heightDifference = usableHeightSansKeyboard - usableHeightNow;
            if (heightDifference > (usableHeightSansKeyboard/4)) {
                // keyboard probably just became visible
                frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
            } else {
                // keyboard probably just became hidden
                frameLayoutParams.height = usableHeightSansKeyboard;
            }
            mChildOfContent.requestLayout();
            usableHeightPrevious = usableHeightNow;
        }
    }

    private int computeUsableHeight() {
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);
        return (r.bottom - r.top);
    }

}

2)手動在布局中添加StatusBar的空間,設置一個25dp的view來搞定乾吻。注意髓梅,可能不同版本的StatusBar高度不同拟蜻,需要用dimen來設備
3)代碼設置根布局的margin;topMagin的值等于狀態(tài)欄的高度枯饿。缺點是每個界面布局需要使用統(tǒng)一的布局格式

//獲取狀態(tài)欄高度
public static int getStatusBarHeight(Context context)
{
    int result = 0;
    int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
    if (resourceId > 0)
    {
        result = context.getResources().getDimensionPixelSize(resourceId);
    }
    return result;
}

該方案在面對淺色狀態(tài)布局內容時酝锅,存在限制。

參考:http://blog.csdn.net/ling9400/article/details/59478358
https://www.zhihu.com/question/31468556

二奢方、沉浸式狀態(tài)欄

如果不需要支持 4.4搔扁,建議使用 statusBarColor
如果需要支持 4.4,建議 4.4 使用 windowTranslucentStatus蟋字;5.x 使用 statusBarColor/colorPrimaryDark

方案如下

//設置狀態(tài)欄顏色
1稿蹲、activity.getWindow().setStatusBarColor(int color)

//因為 FLAT_LAYOUT_STABLE 和 FLAG_LAYOUT_FULLSCREEN 是伴隨 translucentStatus 自動設置的,v21 上需要手動設置
2鹊奖、activity.getWindow()
    .getDecorView()
    .setSystemUiVisibility(
                View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

//調整view的高度场绿,可以動態(tài)設置為StatusBar 的 Height;或者設置padding
3嫉入、<android.support.v7.widget.Toolbar
    android:background="?attr/colorPrimary"
    android:minHeight="?attr/actionBarSize"
    android:elevation="@dimen/space_small"
    android:paddingTop="@dimen/status_bar_height/>

 //dimens.xml
<dimen name="status_bar_height">25dp</dimen>

//values-v23/dimens.xml
<dimen name="status_bar_height">24dp</dimen>

//小米沉浸式狀態(tài)欄
https://dev.mi.com/doc/p=4769/ //

//魅族沉浸式狀態(tài)欄
http://open-wiki.flyme.cn/index.php?title=%E7%8A%B6%E6%80%81%E6%A0%8F%E5%8F%98%E8%89%B2

三、深色狀態(tài)欄方案

注意璧尸,改變狀態(tài)欄文字圖標顏色的代碼咒林,需要在主線程運行。

關于機型判斷爷光,可參考一下文章:
//魅族機型判斷
http://blog.csdn.net/sslinp/article/details/50535188

////如何判斷小米系統(tǒng)
https://dev.mi.com/doc/?p=254

一垫竞、魅族手機設置

//注意該方法需要在setStatusColor調用前設置,否則系統(tǒng)狀態(tài)欄顏色變?yōu)楹谏?public static boolean setMeiZuStatusBarDarkIcon(Window window, boolean dark) {
        boolean result = false;
        if (window != null) {
            try {
                WindowManager.LayoutParams lp = window.getAttributes();
                Field darkFlag = WindowManager.LayoutParams.class.getDeclaredField("MEIZU_FLAG_DARK_STATUS_BAR_ICON");
                Field meizuFlags = WindowManager.LayoutParams.class.getDeclaredField("meizuFlags");
                darkFlag.setAccessible(true);
                meizuFlags.setAccessible(true);
                int bit = darkFlag.getInt(null);
                int value = meizuFlags.getInt(lp);
                if (dark) {
                    value |= bit;
                } else {
                    value &= ~bit;
                }
                meizuFlags.setInt(lp, value);
                window.setAttributes(lp);
                result = true;
            } catch (Exception e) {
                Log.e("MeiZu", "setStatusBarDarkIcon: failed");
            }
        }
        return result;
    }

參考:魅族官網(wǎng)解決方案flyme4+

二蛀序、小米手機方案

    //MIUI 6.0以上
    public static boolean setMIUIStatusBarLightMode(Window window, boolean dark) {
        boolean result = false;
        if (window != null) {
            Class clazz = window.getClass();
            try {
                int darkModeFlag = 0;
                Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams");
                Field  field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
                darkModeFlag = field.getInt(layoutParams);
                Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class);
                if(dark){
                    extraFlagField.invoke(window,darkModeFlag,darkModeFlag);//狀態(tài)欄透明且黑色字體
                }else{
                    extraFlagField.invoke(window, 0, darkModeFlag);//清除黑色字體
                }
                result=true;
            }catch (Exception e){

            }

            //在新的 MIUI 版本(即基于 Android 6.0 欢瞪,開發(fā)版 7.7.13 及以后版本).使用新方案
            //參考http://www.miui.com/thread-8946673-1-1.html
            //https://dev.mi.com/console/doc/detail?pId=1159
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (dark) {
                    int flag = window.getDecorView().getSystemUiVisibility() |
                            View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
                    window.getDecorView().setSystemUiVisibility(flag);
                } else {
                    int flag = window.getDecorView().getSystemUiVisibility() &
                            ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
                    window.getDecorView().setSystemUiVisibility(flag);
                }
            }
        }
        return result;
    }

三、android M(6.0)及以上方案

//compileSdkVersion為6.0及以上
    public boolean setStatusBarLightMode(Activity activity, boolean isFontColorDark) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (isFontColorDark) {
                // 沉浸式
                //                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
                //非沉浸式
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
            } else {
                //非沉浸式
                activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            }
            return true;
        }
        return false;
    }

參考: 小米官網(wǎng)解決方案MIUI6+
其他:
http://www.voidcn.com/blog/wds1181977/article/p-6167721.html
http://blog.csdn.net/jo__yang/article/details/51456126

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末徐裸,一起剝皮案震驚了整個濱河市遣鼓,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌重贺,老刑警劉巖骑祟,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異气笙,居然都是意外死亡次企,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進店門潜圃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來缸棵,“玉大人,你說我怎么就攤上這事谭期《碌冢” “怎么了吧凉?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長型诚。 經(jīng)常有香客問我客燕,道長,這世上最難降的妖魔是什么狰贯? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任也搓,我火速辦了婚禮,結果婚禮上涵紊,老公的妹妹穿的比我還像新娘傍妒。我一直安慰自己,他們只是感情好摸柄,可當我...
    茶點故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布颤练。 她就那樣靜靜地躺著,像睡著了一般驱负。 火紅的嫁衣襯著肌膚如雪嗦玖。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天跃脊,我揣著相機與錄音宇挫,去河邊找鬼。 笑死酪术,一個胖子當著我的面吹牛,可吹牛的內容都是我干的绘雁。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼庐舟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了继阻?” 一聲冷哼從身側響起耻涛,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎抹缕,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卓研,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了奏赘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片寥闪。...
    茶點故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疲憋,靈堂內的尸體忽然破棺而出梁只,到底是詐尸還是另有隱情缚柳,我是刑警寧澤搪锣,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站灰追,受9級特大地震影響,放射性物質發(fā)生泄漏弹澎。R本人自食惡果不足惜努咐,卻給世界環(huán)境...
    茶點故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望麦撵。 院中可真熱鬧溃肪,春花似錦、人聲如沸惫撰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽夯膀。三九已至,卻和暖如春诱建,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工格仲, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留诵冒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓汽馋,卻偏偏與公主長得像,于是被迫代替她去往敵國和親苗桂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,843評論 2 354

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,116評論 25 707
  • 前言 首先請大家看幾張圖: 以上的效果,一般我們統(tǒng)稱為沉浸式狀態(tài)欄木缝。其實,這種叫法不是很準確放案,而且也沒有沉浸式狀態(tài)...
    宇是我閱讀 3,853評論 2 28
  • 概念 全屏模式 變色狀態(tài)欄模式 背景全屏+變色狀態(tài)欄模式 圖片全屏+變色狀態(tài)欄模式 ContentView: ac...
    我不是死胖子閱讀 1,579評論 0 2
  • 同學在朋友圈轉《有幾個當媽的不是神經(jīng)病》矫俺,我復她,你還早厘托,等娃娃到兩歲多,更難對付铅匹。她回我,你是深有體會流礁。 放下手...
    容止若思閱讀 153評論 0 0
  • 鎊美4H上升通道上軌空罗丰,日線前期三角形破位處的壓力。
    瑞祺閱讀 104評論 0 0