In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how to use the fitsSystemWindows attribute of Android". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to use the fitsSystemWindows attribute of Android".
The bar at the top of the Android phone that displays various notifications and status information is called the status bar.
Usually, the content of our application is displayed below the status bar. But sometimes in order to achieve better visual effects, we want to extend the content of the application to the back of the status bar, which can be called an immersive status bar.
So how does the immersive status bar effect be achieved with the help of the android:fitsSystemWindows attribute? Why does this attribute always work from time to time? Next, we will learn and reveal the secrets step by step.
I believe that according to the good idea of most people, the android:fitsSystemWindows property should be like a switch, set to true to turn on the immersive status bar effect, and set to false to turn off the immersive status bar effect. But this is not the case.
Let's demonstrate it with a code example. First of all, in order to verify the effect of the immersive status bar, you need to change the system status bar to a transparent color, as shown in the following code:
Class MainActivity: AppCompatActivity () {override fun onCreate (savedInstanceState: Bundle?) {super.onCreate (savedInstanceState) setContentView (R.layout.activity_main) window.statusBarColor = Color.TRANSPARENT}}
Next, we add the android:fitsSystemWindows attribute to the root layout of activity_main.xml, and set a background color to the layout to observe the effect:
Run the code, and the effect is as follows:
From the background color of the layout, we can see that the content of the layout does not extend to the back of the system status bar. That is, even if the android:fitsSystemWindows property is set, we do not achieve the immersive status bar effect.
But don't worry, we just need to make a few minor changes next, as follows:
As you can see, the root layout has just been changed from FrameLayout to CoordinatorLayout, and nothing else has changed. Then rerun the program. The effect is shown in the following figure:
In this way, the immersive status bar effect can be achieved successfully.
Why does the android:fitsSystemWindows property take effect when set on the CoordinatorLayout layout, but not on the FrameLayout layout?
This is because, after all, the configuration in xml is just a tag, and if you want to have a concrete effect in the application, it depends on how the code handles these tags.
Obviously, FrameLayout doesn't handle the android:fitsSystemWindows property, so it doesn't change whether you set it or not.
Unlike CoordinatorLayout, we can observe its source code, as shown below:
Private void setupForInsets () {if (Build.VERSION.SDK_INT
< 21) { return; } if (ViewCompat.getFitsSystemWindows(this)) { if (mApplyWindowInsetsListener == null) { mApplyWindowInsetsListener = new androidx.core.view.OnApplyWindowInsetsListener() { @Override public WindowInsetsCompat onApplyWindowInsets(View v, WindowInsetsCompat insets) { return setWindowInsets(insets); } }; } // First apply the insets listener ViewCompat.setOnApplyWindowInsetsListener(this, mApplyWindowInsetsListener); // Now set the sys ui flags to enable us to lay out in the window insets setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); } else { ViewCompat.setOnApplyWindowInsetsListener(this, null); }} 可以看到,这里当发现CoordinatorLayout设置了android:fitsSystemWindows属性时,会对当前布局的insets做一些处理,并且调用了下面一行代码: setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN); 这行代码是一切的关键所在。准确来讲,就是因为执行了这行代码,我们才能将布局的内容延伸到系统状态栏区域。 是不是感觉解密了?但事实上CoordinatorLayout所做的事情还远不止这些。 因为沉浸式状态栏其实会带来很多问题。让布局的内容延伸到状态栏的背后,如果一些可交互的控件被状态栏遮挡了怎么办?这样这些控件可能就无法点击和交互了。 CoordinatorLayout为了解决这个问题,会对所有内部的子View都进行一定程度的偏移,保证它们不会被状态栏遮挡住。 比如我们在CoordinatorLayout当中再添加一个按钮: 运行一下程序,效果如下图所示: 可以看到,虽然CoordinatorLayout延伸到了状态栏区域,但是它所包含的按钮是不会进入状态栏区域的,这样就避免了可交互控件被遮挡的情况出现。 但有的朋友会说,如果有些子控件我就是想要让它也延伸到状态栏区域内呢?比如我在CoordinatorLayout内放了一张图片,按照这个规则,图片也是不会显示在状态栏背后的,这样就达不到想要的效果了。 我们可以来试一下这种场景。比如在CoordinatorLayout中再添加一个ImageView,代码如下所示: 现在运行一下程序,效果如下图所示: 确实,图片是不会进入状态栏区域的,和我们之前所解释的理论相符合。 但是很明显,这并不是我们想要的效果,那么有什么办法可以解决呢? 这里我们可以借助其他布局来实现。在Google提供的诸多布局当中,并不是只有CoordinatorLayout会处理android:fitsSystemWindows属性,像CollapsingToolbarLayout、DrawerLayout也是会对这个属性做处理的。 现在对activity_main.xml进行如下修改: 可以看到,这里我们在ImageView的外面又包裹了一层CollapsingToolbarLayout,并且给CollapsingToolbarLayout也设置了android:fitsSystemWindows属性,这样CollapsingToolbarLayout就可以将内容延申到状态栏区域了。 接着我们给ImageView同样设置了android:fitsSystemWindows属性,如此一来,就可以让图片显示在状态栏的背后了。 重新运行一下程序,效果如下图所示: 需要注意的是,CollapsingToolbarLayout一定要结合着CoordinatorLayout一起使用,而不能单独使用。因为CollapsingToolbarLayout只会对内部控件的偏移距离做出调整,而不会像CoordinatorLayout那样调用setSystemUiVisibility()函数来开启沉浸式状态栏。 看到这里,相信大家都已经知道应该如何去实现沉浸式状态栏效果了。但是可能有的朋友会说,由于项目限制的原因,他们无法使用CoordinatorLayout或CollapsingToolbarLayout,而是只能使用像FrameLayout或LinearLayout这样的传统布局,这种情况怎么办呢? 其实我们知道CoordinatorLayout实现沉浸式状态栏的原理之后,自然也就知道如何自己手动实现了,因为本质就是调用setSystemUiVisibility()函数。 现在我们将activity_main.xml改成用传统FrameLayout布局的写法: 为了实现沉浸式状态栏的效果,我们手动在MainActivity当中调用setSystemUiVisibility()函数,来将FrameLayout的内容延伸到状态栏区域: class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) window.statusBarColor = Color.TRANSPARENT val frameLayout = findViewById(R.id.root_layout) frameLayout.systemUiVisibility = (SYSTEM_UI_FLAG_LAYOUT_STABLE or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) }} 这里提醒一点,setSystemUiVisibility()函数其实已经被废弃了。从Android 11开始,Google提供了一个新的API WindowInsetsController来实现同样的功能,不过本篇文章就不往这方面展开了。 现在重新运行一下程序,效果如下图所示: 可以看到,现在我们仍然实现了沉浸式状态栏的效果,但问题是FrameLayout中的按钮也延伸到状态栏区域了,这就是前面所说的可交互控件被状态栏遮挡的问题。 出现这个问题的原因也很好理解,因为之前我们是使用的CoordinatorLayout嘛,它已经帮我们考虑好到这些事情,自动会将内部的控件进行偏移。而现在FrameLayout显然是不会帮我们做这些事情的,所以我们得想办法自己解决。 这里其实可以借助setOnApplyWindowInsetsListener()函数去监听WindowInsets发生变化的事件,当有监听到发生变化时,我们可以读取顶部Insets的大小,然后对控件进行相应距离的偏移。 修改MainActivity中的代码,如下所示: class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) window.statusBarColor = Color.TRANSPARENT val frameLayout = findViewById(R.id.root_layout) frameLayout.systemUiVisibility = (SYSTEM_UI_FLAG_LAYOUT_STABLE or SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) val button = findViewById(R.id.button) ViewCompat.setOnApplyWindowInsetsListener(button) { view, insets ->Val params = view.layoutParams as FrameLayout.LayoutParams params.topMargin = insets.systemWindowInsetTop insets}
As you can see, when the monitor hears that WindowInsets has changed, we can call systemWindowInsetTop to get the height of the status bar, and then offset the controls that do not need to extend to the status bar area.
Rerun the program, as shown in the following figure:
Thank you for your reading, the above is the content of "how to use the fitsSystemWindows attribute of Android". After the study of this article, I believe you have a deeper understanding of how to use the fitsSystemWindows attribute of Android. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.