轉(zhuǎn)載注明出處:簡書-十個雨點
Android開發(fā)雖然不算多難,但其中確實包含了這樣那樣的坑狐蜕,我今天要說的這個坑可能很少人會遇到宠纯,不過萬一呢。层释。婆瓜。
一開始是我想在項目的toolbar上添加谷歌原生支持的搜索功能,但是怎么弄都不對贡羔,鍵盤彈出以后搜索框會自動消失廉白,如下圖所示,可能比較亂乖寒,將就看看吧:
經(jīng)過兩天的不斷修改嘗試猴蹂,終于找到了癥結(jié)所在:
在styles.xml文件中設(shè)置windowTranslucentStatus=true會導(dǎo)致SearchView顯示不正確!
同時還得到一個結(jié)論:
targetSdkVersion對最終編譯結(jié)果有較大的影響楣嘁!
先說targetSdkVersion對最終編譯結(jié)果的影響磅轻,這些影響主要在support庫的界面上。比如同樣使用Theme.AppCompat.Light.NoActionBar逐虚,targetSdkVersion<21編譯的結(jié)果運(yùn)行在api21以上的手機(jī)上聋溜,就不自帶沉浸式狀態(tài)欄。而targetSdkVersion>=21編譯的就自帶沉浸式狀態(tài)欄痊班,不過api19的還是需要使用windowTranslucentStatus來開啟沉浸式狀態(tài)欄的勤婚。
再比如跟上例一樣的targetSdkVersion設(shè)置摹量,用同樣的NotificationCompat生成的通知的顯示效果是不一樣的涤伐,如下圖:
甚至還有更可怕的馒胆,是會影響到一些奇怪的地方,比如友盟的反饋組件界面:
我知道一般人是看不出差別來的凝果,那么看下面這個圖:
這下看得出來了吧祝迂,完全影響到界面布局了,而且語音按鈕的點擊功能也失效了F骶弧P亡ā!
所以為了保證友盟的反饋組件的可用性山害,我只能現(xiàn)在targetSdkVersion=15了纠俭。
具體的原因還不太清楚,可能是我自己本身哪里使用得不太對吧浪慌。冤荆。。
再說回到windowTranslucentStatus权纤。
為什么要設(shè)置windowTranslucentStatus呢钓简?windowTranslucentStatus顧名思義是透明狀態(tài)欄的意思,參照前面所說的汹想,如果targetSdkVersion<21外邓,如果要實現(xiàn)沉浸式的效果,就需要設(shè)置windowTranslucentStatus古掏,或者如果想要api19也實現(xiàn)沉浸式效果损话,無論targetSdkVersion為多少都要設(shè)置windowTranslucentStatus。具體如何實現(xiàn)沉浸式狀態(tài)欄槽唾,可以參考這篇席镀。
那是不是沉浸式狀態(tài)欄和SearchView就不能同時使用了呢?當(dāng)然不是:
- 如果你的targetSdkVersion>=21夏漱,那么只要不給api19設(shè)置沉浸式效果就可以了豪诲,api21以上的版本會自動開啟沉浸式效果,SearchView工作也正常挂绰。
- 如果你的targetSdkVersion<21屎篱,或者你想給api19也設(shè)置沉浸式效果,那么就將styles.xml里面的windowTranslucentStatus刪掉葵蒂,然后使用代碼的方式來實現(xiàn)沉浸式吧交播。
下面是簡單的沉浸式代碼實現(xiàn):
public class StatusBarCompat {
public static void setupStatusBarView(Activity activity, ViewGroup decorViewGroup, boolean on,int colorRes) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
setTranslucentStatus(activity, on);
View mStatusBarTintView = new View(activity);
int mStatusBarHeight = 0;
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
mStatusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
}
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, mStatusBarHeight);
params.gravity = Gravity.TOP;
mStatusBarTintView.setLayoutParams(params);
mStatusBarTintView.setBackgroundResource(colorRes);
mStatusBarTintView.setVisibility(View.VISIBLE);
decorViewGroup.addView(mStatusBarTintView);
}
}
private static void setTranslucentStatus(Activity activity,boolean on) {
Window win = activity.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);
}
}
其實這個WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS的作用和windowTranslucentStatus是一樣的,但是為什么通過代碼的方式和通過資源文件的方式來實現(xiàn)有這么大的差別就不清楚了践付。