實現(xiàn)狀態(tài)欄(statusbar)漸變效果其實很簡單

轉載請標明出處:http://www.itdecent.cn/p/035a7e19fd9b
本文出自:Jlanglang

前言

qq最近更新搞了漸變式狀態(tài)欄.然后...新需求就是要加這個.唉

先來張效果圖:

image.png

常見的方式:

設置Theme,狀態(tài)欄透明.

 <item name="android:windowTranslucentStatus">true</item>

實現(xiàn)起來比較簡單.
比如:SystemBarTint
幾行代碼搞定了.

但是.我要潑冷水,這種方式會引起這些問題:
1.軟鍵盤彈起bug
2.fragment不適應
這種方式的優(yōu)點:

兼容到4.4

我的看法:

1.用全屏模式或者狀態(tài)欄透明的方式去實現(xiàn),感覺很勉強
2.為了一個statusbar的效果,然后去處理一大堆不適應,我認為是不值得的.特別是軟鍵盤彈出的問題
3.如果為了適配4.4,要費這么大功夫的話...

我的實現(xiàn)方式:

1.拿到StatusBar:

很簡單,翻翻DecorView源碼,就能知道,是通過ColorViewState 配置創(chuàng)建的View.

image.png
image.png

由于是私有成員,要拿到對應的參數(shù),一般做法是使用反射.
這里我取了點巧,既然是View,那么就能findviewbyId找到
只要想辦法拿到com.android.internal.R.id.statusBarBackground這個id值就行了

  private void initStatusBar() {
        if (statusBarView == null) {
            //android系統(tǒng)級的資源id得這么拿,不然拿不到
            int identifier = getResources().getIdentifier("statusBarBackground", "id", "android");
            statusBarView = getWindow().findViewById(identifier);
        }
        if (statusBarView != null) {
            statusBarView.setBackgroundResource("你的漸變drawable資源id");
        }
    }

2.等StatusBar繪制完成

如果你直接在onCreate中調(diào)用上面的方法,你會發(fā)現(xiàn),拿到的是null.
這是因為Statusbar還沒繪制完成.
所以,可以在onCreate()中使用Looper.myQueue().addIdleHandler()來保證Statusbar繪制完成后再findview.
然后對DecorView設置addOnLayoutChangeListener監(jiān)聽
當布局發(fā)生變化,就設置statusbar的背景

        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                if (isStatusBar()) {
                    initStatusBar();
                    getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                        @Override
                        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                            initStatusBar();
                        }
                    });
                }
                return false;
            }
        });

3.為什么要addOnLayoutChangeListener:

其實不加監(jiān)聽,也能實現(xiàn)改變statusbar顏色的效果..但是會出現(xiàn)問題
比如彈軟鍵盤后,彈popwindow后,引起window狀態(tài)改變時,
statusbar的顏色就會復原...

基本完整的代碼

   private View statusBarView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        //延時加載數(shù)據(jù).
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {
            @Override
            public boolean queueIdle() {
                if (isStatusBar()) {
                    initStatusBar();
                    getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
                        @Override
                        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
                            initStatusBar();
                        }
                    });
                }
                //只走一次
                return false;
            }
        });
    }
    private void initStatusBar() {
        if (statusBarView == null) {
            int identifier = getResources().getIdentifier("statusBarBackground", "id", "android");
            statusBarView = getWindow().findViewById(identifier);
        }
        if (statusBarView != null) {
               statusBarView.setBackgroundResource("你的漸變drawable資源id");
        }
    }

     protected boolean isStatusBar() {
        return true;
    }

這種方式的缺點:

1.因為沒有使用全屏的模式,所以適配4.4是沒戲了.


交流群:493180098,這是個很少吹水,交流學習的群.

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容