Android定制透明悬浮StatusBar 多分辨率适配

定制透明悬浮StatusBar 多分辨率适配

  1. 修改statusBar需要修改framework下的systemUI,systemUI的目录位于frameworks/base/packages/SystemUI
  2. 设计自定义View(TBarView),放到目录SystemUI的src/com/android/systemui/statusbar下.
  3. 对于TBarView做不同分辨率适配,需要在SystemUI的res/values-480x240,res/values-864x480等不同分辨率下创建对应的dimens.xml
  4. 需要在framework-res下增加status_bar_width并做不同分辨率适配,在framworks/base/core/res/res下创建文件夹values-480x240和values-864x480,并各自创建一个dimens.xml
  5. 在不同文件夹dimens.xml中增加<dimen name="status_bar_width">130dp</dimen>
  6. 在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引用到该资源
  7. 进入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时传入宽度和高度。
  8. 修改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即可)
  9. 修改frameworks/base/policy/src/com/android/internal/policy/impl/PhoneWindowManager(这是实际控制statusBar占据屏幕范围的类)
  10. 在原生系统中,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);
  11. 修改PhoneWindowManager,getConfigDisplayWidth(),返回屏幕宽度减去mStatusBarWidth宽度。getConfigDisplayHeight(),返回整个屏幕的高度。
  12. 修改PhoneWindowManager,selectAnimationLw()if (win == mStatusBar)部分,进入显示动画改成R.anim.dock_right_enter,退出隐藏动画改成R.anim.dock_right_exit
  13. 修改PhoneWidowManager,beginLayoutLw(),分别修改 mStableLeft = mUnrestrictedScreenLeft;, mStableRight = mUnrestrictedScreenWidth - mStatusBarWidth;, mDockLeft = mUnrestrictedScreenLeft;, mDockRight = mUnrestrictedScreenWidth - mStatusBarWidth;, mSystemLeft = mUnrestrictedScreenLeft;, mSystemRight = mUnrestrictedScreenWidth - mStatusBarWidth;
  14. 修改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>

对于动态切换悬浮和非悬浮状态的情况,有两种方案可用:

  1. 使用静态方案,在切换到非悬浮的状态时,对Activity设置padding值,使padding值与statusBar的宽度或高度相等;而切换到悬浮状态时,取消Activity设置的padding值恢复到之前的状态。
  2. 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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值