状态栏透明而实现 "沉浸式" 及兼容问题
2017-11-07 本文已影响54人
_VITA
从我博客园搬过来的
现在很流行ios式的状态栏(透明状态栏,网上说的有点玄乎:沉浸式布局)不过确实很酷炫.网上相关文章可多了 有点杂感觉,没什么逻辑感,我来试试。
先上效果图吧;
-
安卓5.0系统上加Flag直接实现透明状态栏,很简单
drawable背景(5.0系统)
图片背景(5.0),可见有一定压缩 - 安卓4.3系统上 状态栏透明不了 所以一条黑黑的背景
- 安卓4.4系统可以实现透明状态栏,但有可能半黑半透的透明状态栏。
其实没那么复杂 思路上分"两步走"
- 状态栏变透明
- 状态栏下面的 ContentView设置padding_top 去重叠.
补充知识点:
ui层级关系:Activity>PhoneWindow(Framlaout)>DecorView(LinearLayout)>TitleView(我的理解是 StateBar和 ActionBar的容器)+ContentView+底部带Home键的一排ActionBar
我们要处理的就是 DecorView.
针对4.4系统,如何实现"两步走"
第一步:实现透明状态栏
<style name="MyAppCompatNoActionBar" parent="Theme.AppCompat.Light">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item> // 前两个保持和application的theme一样 特别app没有的时候 activity不能有 会空指针
<item name="android:windowIsTranslucent">true</item> //xml实现透明状态栏 对于很多国产手机会失效 所以建议在java代码中再实现一遍
</style>
补充点:在manifest里面 需要透明栏的 activity的 theme设置为(Activity必须使用Theme.AppCompat主题及其子主题)
android:theme="@style/MyAppCompatNoActionBar"
第1.5步:java代码实现状态栏透明(自己封装的StatusBarUtils):
@TargetApi(Build.VERSION_CODES.KITKAT)
public static void setTransparentBar(Activity activity, @ColorInt int color, int alpha) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {//安卓5.0以上 加Flag直接实现透明状态栏
Window window = activity.getWindow();
View decorView = window.getDecorView();
int option = View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
decorView.setSystemUiVisibility(option);
int finalColor = alpha == 0 ? Color.TRANSPARENT :
Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
window.setStatusBarColor(finalColor);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){//安卓4.4以上 获取docoeView并给docoeView设置透明色
Window window = activity.getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup decorView = (ViewGroup) window.getDecorView();
int finalColor = alpha == 0 ? Color.TRANSPARENT :
Color.argb(alpha, Color.red(color), Color.green(color), Color.blue(color));
decorView.addView(createStatusBarView(activity, finalColor));
}//4.4一下实现不了。。
}
第二步:将要显示的页面挪下来,使之不遮挡状态栏
(自己封装的StatusBarUtils)
//获取状态栏高度
public static int getStatusBarHeight(Context context) {
int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
}
return result;
}
要实现透明状态栏的view中:
mIStatusHeight = StatusBarUtils.getStatusBarHeight(this);//会根据安卓版本返回不同值 4.4以下:0;4.4及4.4以上 返回系统statusbar高度
mIToolbarHeightHome = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,48, getResources().getDisplayMetrics());//咱们要显示页面的第一个view的高度
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mToolbar.getLayoutParams();
lp.height = mIStatusHeight + mIToolbarHeightHome;//实际view的高度要加上statusbar的高度,因为后面要padingtop 减去statusbar的高度.
mToolbar.setPadding(0, mIStatusHeight, 0, 0);//减去statusbar的高度.避免覆盖statusbar
然后就完成啦~
最后tip一个:对于4.4的vivo,无法实现透明状态栏.这是vivo手机系统设计的问题。