Android4.4新的特性,在应用内开启透明状态栏和透明虚拟按钮。

除了沉浸模式外,Android 4.4还有新的API,能使应用内的状态栏和虚拟按钮透明。其他更多的Android 4.4 APIs可以看这里

如果要使应用内的状态栏和虚拟按钮变成透明有两种方法。

一种是代码方式:

1 Window window = getWindow();
2 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
3 window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);

另外一种是使用两个新的主题风格:

Theme.Holo.NoActionBar.TranslucentDecorTheme.Holo.Light.NoActionBar.TranslucentDecor

但是这种方式只支持Android4.4以上系统,所以为了保持兼容性,我们还是采用代码方式比较好。只需要先判断,如果是4.4以上系统才启用代码。

开启后上下系统栏都透明了。

但是如果应用本身是带有actionbar或者标题栏的话会就会变得比较尴尬,内容会在上面露出来。这个时候需要在布局文件里加入android:fitsSystemWindows="true"。

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:id="@+id/layout"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:background="#c8c8c8" >
 6     
 7     <ListView
 8         android:id="@+id/listview"
 9         android:layout_width="match_parent"
10         android:layout_height="match_parent" />
11 
12 </RelativeLayout>

加入前                                                                 加入后

              

但是这样的话内容就不能从透明的虚拟按钮下穿过,没原来那么好看。我们可以按照以前一样把根布局设置一个高度为系统栏高度和ActionBar高度的内边距就可以。

同时关于获取ActionBar和状态栏的高度,发现用原来的方法有时候会获取的值为0。自己google找了一下,找到两个前辈提供的获取高度方法,获取ActionBar高度获取状态栏高度

1 if (android.os.Build.VERSION.SDK_INT > 18) {
2             Window window = getWindow();
3             window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
4             window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
5             //设置根布局的内边距
6             RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.layout);
7             relativeLayout.setPadding(0, getActionBarHeight()+getStatusBarHeight(), 0, 0);
8         }
 1 // 获取手机状态栏高度
 2     public int getStatusBarHeight() {
 3         Class<?> c = null;
 4         Object obj = null;
 5         Field field = null;
 6         int x = 0, statusBarHeight = 0;
 7         try {
 8             c = Class.forName("com.android.internal.R$dimen");
 9             obj = c.newInstance();
10             field = c.getField("status_bar_height");
11             x = Integer.parseInt(field.get(obj).toString());
12             statusBarHeight = getResources().getDimensionPixelSize(x);
13         } catch (Exception e1) {
14             e1.printStackTrace();
15         }
16         return statusBarHeight;
17     }
18 
19     // 获取ActionBar的高度
20     public int getActionBarHeight() {
21         TypedValue tv = new TypedValue();
22         int actionBarHeight = 0;
23         if (getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true))// 如果资源是存在的、有效的
24         {
25             actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics());
26         }
27         return actionBarHeight;
28     }

设置后的效果

接下来,因为我自己写的一些应用是暗色的主题的,会导致透明的状态栏和ActionBar颜色不太协调。看到有一些应用是把状态栏的颜色设置成和ActionBar一样,这种解决方法也不错。

具体是怎么实现的也不太清楚,我自己猜测写了一个差不多状态栏。我是直接在根视图加入一个高度为状态栏高度的TextView,背景设置为和ActionBar一样。具体代码如下:

1             // 创建TextView
2             TextView textView = new TextView(this);
3             LinearLayout.LayoutParams lParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, getStatusBarHeight());
4             textView.setBackgroundColor(Color.parseColor("#3F9FE0"));
5             textView.setLayoutParams(lParams);
6             // 获得根视图并把TextView加进去。
7             ViewGroup view = (ViewGroup) getWindow().getDecorView();
8             view.addView(textView);

在模拟器上看还行,但是在实际的手机当中总感觉ActionBar有点过大,所以我在背景色里加入了一些渐变,在实体手机中就比较好看一点,不会觉得ActionBar太宽了。

1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android" >
3     <gradient android:startColor="#c8c8c8"
4         android:endColor="#3F9FE0"
5         android:angle="270"
6         android:type="linear"/>
7 
8 </shape>

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。