Android沉浸式狀態(tài)欄實現(xiàn)及處理鍵盤彈出

爆照

這年頭沒有好看的顏值都不好混,首先來一張全家福。

圖1:沒有實現(xiàn)沉浸式狀態(tài)欄
圖2:導(dǎo)航欄文字被遮蓋住
圖3:導(dǎo)航欄被頂上去
圖4:輸入框被鍵盤遮住
圖5:彈出鍵盤的上邊多了一個狀態(tài)欄高度的白框

圖6:正常樣式.gif

怎么樣添寺,一家六姊妹褪猛,總有一個你符合你的胃口的吧(什么赌结,六個都要吭露,小伙子不要太貪心胺痛椤)。
下面言歸正傳讲竿,分別以沉浸式狀態(tài)欄三種實現(xiàn)方式以及如何完美解決與鍵盤沖突兩大方面說起

沉浸式狀態(tài)欄的三種實現(xiàn)方式

概述:大家都知道纬向,實現(xiàn)沉浸式狀態(tài)欄這種特性最低兼容到android4.4,所以4.4之下的就不用去考慮了

方式一:設(shè)置ToolBar的Padding

Don't BB show me the code

mToolbar = (Toolbar) findViewById(R.id.toolbar);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            //透明狀態(tài)欄
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
            mToolbar.setPadding(mToolbar.getPaddingLeft(),getStatusBarHeight(this),
                    mToolbar.getPaddingRight(),mToolbar.getPaddingBottom());
        }
        mToolbar.setTitle("測試一");
        setSupportActionBar(mToolbar);

getStatusBarHeight(this)獲取沉浸式狀態(tài)欄高度代碼

 //通過反射獲取狀態(tài)欄高度,默認(rèn)25dp
    private static int getStatusBarHeight(Context context) {
        int statusBarHeight = dip2px(context, 25);
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height = Integer.parseInt(clazz.getField("status_bar_height")
                    .get(object).toString());
            statusBarHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusBarHeight;
    }

這樣就是就不需要我們在xml布局里面設(shè)置android:fitsSystemWindows="true"屬性避免ToolBar被狀態(tài)欄給遮蓋住
PS:當(dāng)然也可以不用ToolBar通過include一個布局替換戴卜,然后設(shè)置該布局的marginTop就行,不過不建議這么做

方式二:設(shè)置屬性

android:fitsSystemWindows="true

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            //透明狀態(tài)欄
         getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
        }
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <android.support.v7.widget.Toolbar
        android:fitsSystemWindows="true"
        android:id="@+id/toolbar"
        android:background="@color/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:minHeight="?attr/actionBarSize"/>
</LinearLayout>

在ToolBar增加屬性android:fitsSystemWindows="true"就行了
fitSystemWindows屬性的官方描述:
Boolean internal attribute to adjust view layout based on system windows such as the status bar. If true, adjusts the padding of this view to leave space for the system windows. Will only take effect if this view is in a non-embedded activity.

方式三:使用SystemBarTint框架

appbuild.gradle添加依賴

compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'

主要設(shè)置代碼如下琢岩,具體可以參考SystemBarTint官方Demo

 mToolbar = (Toolbar) findViewById(R.id.toolbar);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            setTranslucentStatus(true);
        }

        // 創(chuàng)建狀態(tài)欄的管理實例
        SystemBarTintManager tintManager = new SystemBarTintManager(this);
        // 激活狀態(tài)欄設(shè)置
        tintManager.setStatusBarTintEnabled(true);
        // 激活導(dǎo)航欄設(shè)置投剥,當(dāng)使用actionbar的時候開啟
        tintManager.setNavigationBarTintEnabled(true);
        // 設(shè)置一個顏色給系統(tǒng)欄
        tintManager.setTintColor(Color.parseColor("#990000FF"));
        // 設(shè)置狀態(tài)欄需顏色或背景圖
        tintManager.setStatusBarTintResource(R.color.colorAccent);
        mToolbar.setTitle("測試三");
        setSupportActionBar(mToolbar);
 /**
     * 是否設(shè)置沉浸式
     * @param on
     */
    @TargetApi(19)
    private void setTranslucentStatus(boolean on) {
        Window win = getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
        if (on) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
        }
        win.setAttributes(winParams);
    }

完美解決與鍵盤沖突

最后講講我們在使用沉浸式結(jié)合輸入框遇到的坑
回顧一下之前開始我們的六朵金花,最開始我們使用輸入框(當(dāng)然輸入框位置加上軟鍵盤的高度高于屏幕高度)會出現(xiàn)圖三的情況担孔,很直接想到的是忘記在Activity設(shè)置軟鍵盤彈出模式,我們設(shè)置了

 <activity android:name=".TestOneActivity"
            android:windowSoftInputMode="adjustResize"/>

發(fā)現(xiàn)并沒有什么卵用(其實還是有卵用的江锨,至少不會出現(xiàn)標(biāo)題欄上移的情況.....雖然出現(xiàn)軟鍵盤遮蓋了輸入框)。
其實糕篇,這個問題gitHub上早就有大牛有解決方案了啄育,他把他說成是googlebug,并給了相應(yīng)的解決方式AndroidBug5497Workaround
使用很簡單拌消,在Activity onCreate 里的setContentView 方法之后調(diào)用AndroidBug5497Workaround2.assistActivity(this);

 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test_one);
       AndroidBug5497Workaround.assistActivity(this);
}

運行挑豌,出現(xiàn)了圖5的結(jié)果,發(fā)現(xiàn)已經(jīng)幾乎符合我們的要求墩崩,可是仔細(xì)的看氓英,會看到軟鍵盤上面比圖6多了一個狀態(tài)欄高度的白邊
這時候我們需要修改一下AndroidBug5497Workaround類里面的computeUsableHeight函數(shù)

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

        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;
        Rect r = new Rect();
        mChildOfContent.getWindowVisibleDisplayFrame(r);

        //這個判斷是為了解決19之后的版本在彈出軟鍵盤時,鍵盤和推上去的布局(adjustResize)之間有黑色區(qū)域的問題
        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
            return (r.bottom - r.top)+statusBarHeight;
        }
        return (r.bottom - r.top);
    }

下面代碼就是在大牛的基礎(chǔ)上增加上狀態(tài)欄的高度鹦筹,至此铝阐,你成功達(dá)到了圖6的效果。

插曲

為了實現(xiàn)ViewPager+Fragment+Menu(每個Fragment有各自的menu)铐拐,我把創(chuàng)建menu的方法搬到了每個Fragment里徘键,在Fragment的OnCreate設(shè)置setHasOptionsMenu(true);(中間涉及到ViewPager回調(diào)監(jiān)聽一些處理的細(xì)節(jié),這里不作詳細(xì)描述)好不容易在我的華為榮耀6實現(xiàn)了遍蟋,發(fā)現(xiàn)在華為榮耀8不行吹害,后來google了好久知道了我看到這里 https://github.com/JakeWharton/ActionBarSherlock/issues/48,一個Jake Wharton大神提出的Android的一個bug匿值,里面給了解決的方法赠制,是需要繼承相應(yīng)封裝的Fragment和Activity,因為我已經(jīng)有基類了不太好修改,所以直接決定放棄了ToolBar+Menu 改成include布局钟些。(這一塊有時間我整理整理)

最后獻(xiàn)上gitHub鏈接android-transparent-status,歡迎star

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烟号,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子政恍,更是在濱河造成了極大的恐慌汪拥,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙耗,死亡現(xiàn)場離奇詭異迫筑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宗弯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進(jìn)店門脯燃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蒙保,你說我怎么就攤上這事辕棚。” “怎么了邓厕?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵逝嚎,是天一觀的道長。 經(jīng)常有香客問我详恼,道長补君,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任昧互,我火速辦了婚禮挽铁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘敞掘。我一直安慰自己屿储,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布渐逃。 她就那樣靜靜地躺著够掠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪茄菊。 梳的紋絲不亂的頭發(fā)上疯潭,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天,我揣著相機(jī)與錄音面殖,去河邊找鬼竖哩。 笑死,一個胖子當(dāng)著我的面吹牛脊僚,可吹牛的內(nèi)容都是我干的相叁。 我是一名探鬼主播筷黔,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼晒衩,長吁一口氣:“原來是場噩夢啊……” “哼基茵!你這毒婦竟也來了漓拾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤虑润,失蹤者是張志新(化名)和其女友劉穎成玫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拳喻,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡哭当,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了冗澈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片钦勘。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖亚亲,靈堂內(nèi)的尸體忽然破棺而出个盆,到底是詐尸還是另有隱情,我是刑警寧澤朵栖,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站柴梆,受9級特大地震影響陨溅,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜绍在,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一门扇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧偿渡,春花似錦臼寄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至适揉,卻和暖如春留攒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嫉嘀。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工炼邀, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人剪侮。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓拭宁,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子杰标,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內(nèi)容