android 自定义状态栏和导航栏分析与实现

King14T 5年前
   <h2>效果</h2>    <p>android 4.4之后,系统是支持自定义状态栏和导航栏的,举个最典型的例子就是bilibili客户端了(iOS版本和android版本能用两套完全不一样符合各自系统的设计ui,良心啊~),顶部状态栏为粉色,底部导航栏为半透明色:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/088567831743e2fd3eb4705b20e6ad6b.png"></p>    <p>接着QQ最新的版本6.2也使用了状态栏透明风格,但是出来的效果在不同版本,不同手机上,显示的效果真是差异很大(4.3版本是无法使用状态栏透明风格的,只是放出来做个对比):</p>    <p>更新,QQ的6.2.1版本已经重新换成蓝色的bar了。</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/c402d472a556c856960385a852162dca.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/05406103177afbab36abcc7db0e252b0.png"></p>    <p> </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/4340a59ad467d125bebc6041158071ae.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/40eb278c7ad499acba86879bc9bc309c.png"></p>    <p> </p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/0f7a9c6e049c49b58d166503a46af163.png"></p>    <p> </p>    <p>这个我也不知道到底是怎么适配的,希望有人给解答一下。</p>    <h2>实现与分析</h2>    <h3>API 19~20</h3>    <p>接下来分析一下怎么自定义状态栏和导航栏,这个在21版本之前和之后可以使用不同的方式来实现,先看看19~20版本的适配,状态栏和导航栏透明:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <resources>      <style name="Activity_translucent_status_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">          <item name="android:windowTranslucentStatus">true</item>      </style>      <style name="Activity_translucent_navigation_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">          <item name="android:windowTranslucentStatus">true</item>          <item name="android:windowTranslucentNavigation">true</item>      </style>  </resources></code></pre>    <p>从代码看到,状态栏透明主要是使用android:windowTranslucentStatus属性,导航栏透明主要是使用android:windowTranslucentNavigation属性。当这个属性设置为true之后,系统栏会变成半透明,并且应用的内容区域也会扩充到系统栏中:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/eaba843779e44ad9a8171e70ea462007.png"></p>    <p>这样目的是达到了,但是效果肯定是不行的,怎么解决呢?来学习一下bilibili和QQ的布局就了解了:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/09df0da0246c01c1b01bf465d56ff097.jpg"></p>    <p style="text-align:center">bilibili</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/90bf2970746e68ed7d1825dfc34aed72.jpg"></p>    <p style="text-align:center">QQ</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/65b9fa7126f03d39dfc5d8286f8cb0db.jpg"></p>    <p style="text-align:center">QQ</p>    <p>从图片中可以很清楚的看到bilibili和QQ都是在顶部放置了一个和status bar一样高度,自定义颜色的view,status bar高度的获取方式:</p>    <pre>  <code class="language-java">int id = getResources().getIdentifier("status_bar_height", "dimen", "android");  int height = getResources().getDimensionPixelOffset(id);</code></pre>    <p>这样思路就很清楚了,所有的activity继承自一个基类activity,基类activity的布局文件进行类似的处理,最后也是能够达到和bilibili客户端一样的效果(吐槽一下华为p6的状态栏黑色阴影真心难看):</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f6eb372d34a82751cb7188c04c10fed8.png"></p>    <p>github上也有相关库可以实现一样的效果,但是原理都差不多。</p>    <h3>API 21~++</h3>    <p>21版本和21版本之后,系统增加了更多的选项用来提供用户修改颜色:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/8d2edbe8b630654c341eb760a8e95f6f.png"></p>    <p>所以可以通过android:colorPrimaryDark属性来使状态栏变成所需的颜色,android:navigationBarColor属性来改变导航栏所需要的颜色:</p>    <pre>  <code class="language-java"><item name="android:colorPrimaryDark">@color/bar_color</item>  <item name="android:navigationBarColor">@color/half_black_transparent</item></code></pre>    <p>最后效果:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/6f130f4e08eff1f4cf692ec4171bd86b.png"></p>    <p>貌似这个导航栏是无法使用透明颜色的,那么导航栏透明的方案这么做是行不通的,只能继续使用19版本的方案了:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="utf-8"?>  <resources>      <style name="Activity_translucent_status_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">          <item name="android:colorPrimaryDark">@color/bar_color</item>      </style>      <style name="Activity_translucent_navigation_bar" parent="@style/Theme.AppCompat.Light.NoActionBar">          <item name="android:windowTranslucentStatus">true</item>          <item name="android:windowTranslucentNavigation">true</item>      </style>  </resources></code></pre>    <p>最后也当然需要在顶部添加一个status bar高度的自定义view了,最后不同版本,不同机型适配效果:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f0d33627d2957f388a7604aa00fd5f0f.jpg"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/b789de6e41fd28edb578448c630e47d7.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/cf560670714549eae8fddfb5c3f6eb3f.png"></p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5e805da375de985bdb4c549859c0ff99.jpg"></p>    <p>适配效果还算可以,如果有其他更好解决方法的,指点一下,谢谢~</p>    <h3> </h3>    <p> </p>    <p>来自:https://juejin.im/post/58f46161b123db632b40a147</p>    <p> </p>