自从Android Studio使用以来,那是各种开发方便啊!什么状态栏,导航栏轻松搞定。而Eclipse开发就没那么开心了。又不能complete.有时还不能找到相应的开发Jar包。这可苦了有些公司还用Eclipse开发的码农了。只能靠自己解决。今天就发篇实用干货。还是费了好大一番时间查找资料的。下面就开始讲解使用沉浸式状态栏之旅:
一个Android应用程序的界面上其实是有很多系统元素的,观察下图:
可以看到,有状态栏、ActionBar、导航栏等。而打造沉浸式模式的用户体验,就是要将这些系统元素全部隐藏,只留下主体内容部分 但是一般不是做游戏的话。我们都只会隐藏状态栏。其他的看需求了。
先上个实现效果图看看(图片粗糙了点):
因为Android在4.4以后才引入的状态栏修改。所以实现的效果都至少在4.4及以后的版本;
代码实现图一部分:
/**
* 设置状态栏颜色
*
* @param activity
* 需要设置的activity
* @param color
* 状态栏颜色值
* @param statusBarAlpha
* 状态栏透明度
*/
public static void setColor(Activity activity, int color, int statusBarAlpha) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
activity.getWindow()
.addFlags(
WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
activity.getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
activity.getWindow().setStatusBarColor(
calculateStatusColor(color, statusBarAlpha));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
activity.getWindow().addFlags(
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
ViewGroup decorView = (ViewGroup) activity.getWindow()
.getDecorView();
int count = decorView.getChildCount();
if (count > 0
&& decorView.getChildAt(count - 1) instanceof StatusBarView) {
decorView.getChildAt(count - 1).setBackgroundColor(
calculateStatusColor(color, statusBarAlpha));
} else {
StatusBarView statusView = createStatusBarView(activity, color,
statusBarAlpha);
decorView.addView(statusView);
}
setRootView(activity);
}
}
当然除了上面的代码以外,还需要修改两个重要的地方
①在Style里面将App样式修改一下:
②将布局xml文件的根部局加上 android:fitsSystemWindows="true" 代表窗口从此Layout开始计算。能让标题与状态栏不重叠效果。不然又坑了。
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowActionBar">false</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@color/white</item> <!-- 窗口背景颜色 -->
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowNoTitle">true</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowTranslucentStatus">true</item>
</style>
我试过改成其他的样式不行。还和theme有关。
我将theme修改为 android:theme="@android:style/Theme.Holo.Light.NoActionBar"
出现的效果:
android:theme="@android:style/Theme.Dialog" //Activity显示为对话框模式
android:theme="@android:style/Theme.NoTitleBar" //不显示应用程序标题栏
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" //不显示应用程序标题栏,并全屏
android:theme="Theme.Light " //背景为白色
android:theme="Theme.Light.NoTitleBar" //白色背景并无标题栏
android:theme="Theme.Light.NoTitleBar.Fullscreen" //白色背景,无标题栏,全屏
android:theme="Theme.Black" //背景黑色
android:theme="Theme.Black.NoTitleBar" //黑色背景并无标题栏
android:theme="Theme.Black.NoTitleBar.Fullscreen" //黑色背景,无标题栏,全屏
android:theme="Theme.Wallpaper" //用系统桌面为应用程序背景
android:theme="Theme.Wallpaper.NoTitleBar" //用系统桌面为应用程序背景,且无标题栏
android:theme="Theme.Wallpaper.NoTitleBar.Fullscreen" //用系统桌面为应用程序背景,无标题栏,全屏
android:theme="Theme.Translucent" //透明背景
android:theme="Theme.Translucent.NoTitleBar" //透明背景并无标题
android:theme="Theme.Translucent.NoTitleBar.Fullscreen" //透明背景并无标题,全屏
android:theme="Theme.Panel " //面板风格显示
android:theme="Theme.Light.Panel" //平板风格显示
图二代码实现部分:
/**
* @author: ZQF_DemoStyle
* @类 说 明:将采用沉浸式
* @version 1.0
* @创建时间:2016-11-16 下午2:30:23
*
*/
public class ThirdActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.third_layout);
initview();
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus && Build.VERSION.SDK_INT >= 19) {
View decorview = getWindow().getDecorView();
decorview.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
// | View.SYSTEM_UI_FLAG_FULLSCREEN
// | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);
}
}
@SuppressWarnings("deprecation")
private void initview() {
ImageView iv = (ImageView) findViewById(R.id.iv);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;
options.inPurgeable = true;
options.inInputShareable = true;
InputStream is = getResources().openRawResource(R.drawable.one);
iv.setImageBitmap(BitmapFactory.decodeStream(is));
}
}
讲解下图片为背景时候调用getWindow().getDecorView()方法获取到了当前界面的DecorView,
然后调用它的setSystemUiVisibility()方法来设置系统UI元素的可见性。其中,
SYSTEM_UI_FLAG_FULLSCREEN表示全屏的意思,也就是会将状态栏隐藏。
SYSTEM_UI_FLAG_LAYOUT_STABLE两个Flag必须要结合在一起使用.表示会让应用的主体内容占用系统状态栏的空间,最后再调用Window的setStatusBarColor()方法将状态栏设置成透明色就可以了。
另外,根据Android的设计建议,ActionBar是不应该独立于状态栏而单独显示的,也将此隐藏起来。我在Style.XML里面已经全部设置好了。可以看一下。
后面为开发方便整理一个工具类StatusBarUtil供大家使用。全部代码也将在下面附上。
下面再来看看另外一种情况:
万一背景全部是白色的怎么办。状态栏的颜色可全部是白色字体啊。那样使用的话不就全部看不见了。是的,确实是看不见了。那怎么解决。两种办法:
①改变状态栏颜色设置一个淡灰色有一点点效果就可以。这样也是不错的。
可是就是想要白色背景的时候怎么办?难道要自定义? 貌似MIUI和MEIZU就是
看看怎么实现的:
/**
* 设置状态栏黑色字体图标, 适配4.4以上版本MIUIV、Flyme和6.0以上版本其他Android
*
* @param activity
* @return 1:MIUUI 2:Flyme 3:android6.0
*/
public static int StatusBarLightMode(Activity activity) {
int result = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
if (MIUISetStatusBarLightMode(activity.getWindow(), true)) {
result = 1;
} else if (FlymeSetStatusBarLightMode(activity.getWindow(), true)) {
result = 2;
}
}
return result;
}
/**
* 设置状态栏字体图标为深色,需要MIUIV6以上
*
* @param window
* 需要设置的窗口
* @param dark
* 是否把状态栏字体及图标颜色设置为深色
* @return boolean 成功执行返回true
*
*/
public static boolean MIUISetStatusBarLightMode(Window window, boolean dark) {
boolean result = false;
if (window != null) {
Class clazz = window.getClass();
try {
int darkModeFlag = 0;
Class layoutParams = Class
.forName("android.view.MiuiWindowManager$LayoutParams");
Field field = layoutParams
.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE");
darkModeFlag = field.getInt(layoutParams);
Method extraFlagField = clazz.getMethod("setExtraFlags",
int.class, int.class);
if (dark) {
extraFlagField.invoke(window, darkModeFlag, darkModeFlag);// 状态栏透明且黑色字体
} else {
extraFlagField.invoke(window, 0, darkModeFlag);// 清除黑色字体
}
result = true;
} catch (Exception e) {
}
}
return result;
}
未完待续。。。。。。。。
Demo源码地址下载:Android状态栏一体化(沉浸式)的实现(Eclipse版)
参考文章:http://blog.csdn.net/sinyu890807/article/details/51763825