我是靠谱客的博主 故意中心,这篇文章主要介绍从设置Android透明状态栏和深色模式了解Activity的结构View前言做一个简单的状态栏设置通用类研究Activity主View总结参考资料,现在分享给大家,希望可以做个参考。

前言

开始,想写一个设置状态栏的通用类,之后又需要结合小米和6.0之后状态栏字体变为黑色等,就找了些资料。
一下子就实现了功能,觉得也挺快的。然后做了一些就想了解一下一个Activity的布局到底有那些view,因为,我们对一些没有放出接口的方法,只能用反射才能获取,然后再设置属性。所以想着就了解一下Activity的View布局


做一个简单的状态栏设置通用类

开始都是copy代码,所以很简单的设置了以下方法。

这边加入使用的测试手机是 红米2

这边是只考虑了api19的情况,就先放简单的代码

  • 设置状态栏透明化
复制代码
1
2
3
4
5
6
7
8
9
public static void setStatusBarTranslucent(Activity activity){ Window window = activity.getWindow(); if (Build.VERSION.SDK_INT >= 19) { //透明状态栏 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); //透明导航栏 window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION); } }
  • 获取状态栏高度
复制代码
1
2
3
4
public static int getStatusBarHeight(Context context){ int barId = context.getResources().getIdentifier("status_bar_height", "dimen", "android"); return context.getResources().getDimensionPixelSize(barId); }
  • 添加状态栏view
复制代码
1
2
3
4
5
6
7
8
public static void addStatusBarView(Activity activity){ View view = new View(activity); view.setBackgroundColor(Color.RED); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, getStatusBarHeight(activity)); ViewGroup group = activity.findViewById(android.R.id.content); group.addView(view, lp); }
  • 设置小米状态栏黑色字体
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static boolean setMIUIBar(Activity activity, boolean dark){ Window window = activity.getWindow(); if (window != null) { Class clazz = window.getClass(); try { int modeFlag; Class layoutParams = Class.forName("android.view.MiuiWindowManager$LayoutParams"); Field field = layoutParams.getField("EXTRA_FLAG_STATUS_BAR_DARK_MODE"); modeFlag = field.getInt(layoutParams); Method extraFlagField = clazz.getMethod("setExtraFlags", int.class, int.class); if (dark) { //透明状态栏 黑色字体 extraFlagField.invoke(window, modeFlag, modeFlag); }else { //白色字体 extraFlagField.invoke(window, 0, modeFlag); } //开发版 7.7.13及以后版本采用了安卓6.0系统API setBarMode(activity, dark); return true; }catch (Exception e){ } } return false; }
  • 设置6.0以上状态栏深色字体
复制代码
1
2
3
4
5
6
7
8
9
10
public static void setBarMode(Activity activity, boolean dark){ View decorView = activity.getWindow().getDecorView(); if (Build.VERSION.SDK_INT >= 23) { if (dark) { decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR); }else { decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE); } } }

然后我们设置到Activity上面

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("-s-", "sdk = "+ Build.VERSION.SDK_INT); StatusBarUtils.setStatusBarTranslucent(this); StatusBarUtils.addStatusBarView(this); StatusBarUtils.setMIUIBar(this, true); }

效果如下

  1. 在xml布局中的效果
    xml布局中的效果

  2. 实际效果
    实际效果

  3. 发现好像被自带的ActionBar给挡住了,我们到style中加入一个没有ActionBar的设置之后
    NoActionBar

  4. 之后我们在activity_main中最外层布局加入android:fitsSystemWindows="true"
    fitsSystemWindows=true

到目前为止我们确实就完成了设置状态栏的背景颜色,修改状态栏的字体了!

本来这样就结束了,之后也就稍微写规范点就可以实现通用类的设置了。
但是,之后想看看到底Activity底下的View到底是什么。


研究Activity主View

从上面的设置我可以知道两个很有用的信息。
1.android.R.id.content
2.getWindow().getDecorView()

这两个到底代表什么呢
我对代码做了如下修改

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.e("-s-", "sdk = "+ Build.VERSION.SDK_INT); // StatusBarUtils.setStatusBarTranslucent(this); // // StatusBarUtils.addStatusBarView(this); // // StatusBarUtils.setMIUIBar(this, true); ViewGroup decorView = (ViewGroup) getWindow().getDecorView(); Log.e("-s-", "decorView getChildCount = "+ decorView.getChildCount()); for (int i = 0; i < decorView.getChildCount(); i++) { Log.e("-s-", "getClassName = "+ decorView.getChildAt(i).getClass().getName()); } ViewGroup content = findViewById(android.R.id.content); Log.e("-s-", "content getChildCount = "+ content.getChildCount()); for (int i = 0; i < content.getChildCount(); i++) { Log.e("-s-", "getClassName = "+ content.getChildAt(i).getClass().getName()); } } }

观察到如下log

复制代码
1
2
3
4
5
E/-s-: sdk = 19 E/-s-: decorView getChildCount = 1 E/-s-: getClassName = android.widget.LinearLayout E/-s-: content getChildCount = 1 E/-s-: getClassName = android.support.constraint.ConstraintLayout

我查了下百度

一、DecorView为整个Window界面的最顶层View。

二、DecorView只有一个子元素为LinearLayout。代表整个Window界面,包含通知栏,标题栏,内容显示栏三块区域。

三、LinearLayout里有两个FrameLayout子元素。

原文 Android DecorView浅析

为了看下实际我也打开了Android Device Monitor查看
布局排序

大体上我们就可以通过上面的布局知道了两个的关联了。

而且我们开始设置的时候,发现添加BarView是在android.R.id.content中添加一个高度和默认状态栏一样高度的view,所以我就试验一下取消addStatusBarView的注释

单独添加barview

复制代码
1
2
3
4
5
6
E/-s-: sdk = 19 E/-s-: decorView getChildCount = 1 E/-s-: getClassName = android.widget.LinearLayout E/-s-: content getChildCount = 2 E/-s-: getClassName = android.support.constraint.ConstraintLayout E/-s-: getClassName = android.view.View

之后我把setStatusBarTranslucent也打开了,然后就是正常的设置了状态栏的颜色。
然后我又做了添加多个addStatusBarView,发现确实添加了多个barview。

至此我们可以确认,状态栏是单独一个由系统控制好了的,然后我们修改状态栏的颜色其实就是设置flag将系统默认的状态栏view去掉。然后让布局能够整个填充,然后我们在content 这个view中加入新的barview和原来的setContentView(R.layout.activity_main)之后我们在未最外层添加一个android:fitsSystemWindows="true"属性让setContentView加入的view能够在content已经添加好的view之下,就实现了修改状态栏颜色。

大概就是这样吧!

大概变化

为了证实 我做了如下实验
我不设置最外层的fitsSystemWindows属性,而是为最外层添加一个topMargin

修改代码如下

复制代码
1
2
3
4
5
6
7
8
for (int i = 0; i < content.getChildCount(); i++) { Log.e("-s-", "getClassName = "+ content.getChildAt(i).getClass().getName()); // content.getChildAt(0).setFitsSystemWindows(true); ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) content.getChildAt(0).getLayoutParams(); lp.topMargin = StatusBarUtils.getStatusBarHeight(this); content.getChildAt(0).setLayoutParams(lp); }

最后的结果却是和设置fitsSystemWindows属性一模一样!



总结

用了这么久,以前也知道DecorView和content,只是没这么深入的了解一下。趁着这次设置就实地的深入学习了下。


参考资料

白底黑字!Android浅色状态栏黑色字体模式
Android DecorView浅析

最后

以上就是故意中心最近收集整理的关于从设置Android透明状态栏和深色模式了解Activity的结构View前言做一个简单的状态栏设置通用类研究Activity主View总结参考资料的全部内容,更多相关从设置Android透明状态栏和深色模式了解Activity内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部