Android定制透明悬浮StatusBar 多分辨率适配
Posted 苦逼程序员_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android定制透明悬浮StatusBar 多分辨率适配相关的知识,希望对你有一定的参考价值。
定制透明悬浮StatusBar 多分辨率适配
- 修改statusBar需要修改framework下的systemUI,systemUI的目录位于frameworks/base/packages/SystemUI
- 设计自定义View(TBarView),放到目录SystemUI的src/com/android/systemui/statusbar下.
- 对于TBarView做不同分辨率适配,需要在SystemUI的res/values-480x240,res/values-864x480等不同分辨率下创建对应的dimens.xml
- 需要在framework-res下增加status_bar_width并做不同分辨率适配,在framworks/base/core/res/res下创建文件夹values-480x240和values-864x480,并各自创建一个dimens.xml
- 在不同文件夹dimens.xml中增加
<dimen name="status_bar_width">130dp</dimen>
- 在frameworks/base/core/res/res/values/symbols.xml中增加
<java-symbol type="dimen" name="status_bar_width" />
,只有增加后才能在system其他位置通过com.android.internal.R.dimen.status_bar_width
引用到该资源 - 进入src/com/android/systemui/statusbar/phone,复制一份PhoneStatusBar到src/com/android/systemui/statusbar/改名为MyStatusBar,修改R.layout.status_bar布局,加入自定义view,在addStatusBarWindow()中通过
getDimension(com.android.internal.R.dimen.status_bar_width)
获取statusBar的宽度,初始化LayoutParams时传入宽度和高度。 - 修改src/com/android/systemui/statusbar/SystemBars,
createStatusBarFromConfig()
,Class<?> cls = MyStatusBar.class;
(后来才发现,SystemBars初始化StatusBar是可以动态配置的,不需要修改SystemBars的任何代码,因为SystemBars是读取res/values/config.xml里面config_statusBarComponent获取到StatusBar的全路径类名,所以只要修改config.xml文件把com.android.systemui.statusbar.phone.PhoneStatusBar,修改为com.android.systemui.statusbar.MyStatusBar即可) - 修改frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager(这是实际控制statusBar占据屏幕范围的类)
- 在原生系统中,statusBar是从上往下占据一定位置的,所以系统中会读取
com.android.internal.R.dimen.status_bar_height
到mStatusBarHeight变量中,而这里定制的系统statusBar是从右到左占据屏幕一定位置的,所以仿照mStatusBarHeight的逻辑,创建变量mStatusBarWidth:mStatusBarWidth = (int)mContext.getResources().getDimension(com.android.internal.R.dimen.status_bar_width);
- 修改PhoneWindowManager,
getConfigDisplayWidth()
,返回屏幕宽度减去mStatusBarWidth宽度。getConfigDisplayHeight()
,返回整个屏幕的高度。 - 修改PhoneWindowManager,
selectAnimationLw()
,if (win == mStatusBar)
部分,进入显示动画改成R.anim.dock_right_enter
,退出隐藏动画改成R.anim.dock_right_exit
。 - 修改PhoneWidowManager,
beginLayoutLw()
,分别修改mStableLeft = mUnrestrictedScreenLeft;
,mStableRight = mUnrestrictedScreenWidth - mStatusBarWidth;
,mDockLeft = mUnrestrictedScreenLeft;
,mDockRight = mUnrestrictedScreenWidth - mStatusBarWidth;
,mSystemLeft = mUnrestrictedScreenLeft;
,mSystemRight = mUnrestrictedScreenWidth - mStatusBarWidth;
- 修改PhoneWindowManager,
getSystemDecorLayerLw()
,if (mStatusBar != null) return 0;
,配合SystemUI/res/layout/status_bar.xml
,android:background="#00000000"
,实现透明背景导航栏,参考Android 设置系统SystemUI 顶部StatusBar状态栏透明一体化
在app中使透明状态栏悬浮在上方
对于静态的情况,只需要activity增加android:windowTranslucentStatus
到style中即可实现
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
对于动态切换悬浮和非悬浮状态的情况,有两种方案可用:
- 使用静态方案,在切换到非悬浮的状态时,对Activity设置padding值,使padding值与statusBar的宽度或高度相等;而切换到悬浮状态时,取消Activity设置的padding值恢复到之前的状态。
- Activity动态设置
android:windowTranslucentStatus
状态,参考资料:fitSystemWindows programmatically for status bar transparency
if(test)
Log.d(TAG, "fit true ");
relativeLayout.setFitsSystemWindows(true);
relativeLayout.requestFitSystemWindows();
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
else
Log.d(TAG, "fit false");
relativeLayout.setFitsSystemWindows(false);
relativeLayout.requestFitSystemWindows();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
以上是关于Android定制透明悬浮StatusBar 多分辨率适配的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Flutter 中使 StatusBar 对 Android 透明
Android棒棒糖中的透明actionBar和statusBar
Lollipop:在 statusBar 后面绘制,其颜色设置为透明