android系统开发——statusbar方向修改

众所周知,statusbar显示在设备的顶部,那怎么改变statusbar的方向呢?
2017年的时候,有在后视镜上做过把statusbar由顶部移到右边,现在我把方法简单的记录下来,statusbar的运行是一个很复杂的流程,所以定制statusbar不是一个很简单的事。
说到statusbar,做android系统开发的软件开发工程师第一个想到的就是SystemUI,说到SystemUI就会想到navigation bar,statusbar,notification。如果对SystemUI有一点了解的话就会知道navigation bar和statusbar的流程大致是一样的,而且navigation bar可以显示在设备的底部或者右侧,因此,我们只要跟踪到navigation bar的方向显示,statusbar的方向显示修改就易如反掌了。
接下来说说navigation bar的方向显示。
navigation bar的方向是在PhoneWindowManager.java控制的,是在beginLayoutLw()函数。
mNavigationBar.computeFrameLw(mTmpNavigationFrame, mTmpNavigationFrame,
mTmpNavigationFrame, mTmpNavigationFrame, mTmpNavigationFrame, dcf,
mTmpNavigationFrame);//navigation bar在设备上显示坐标
mNavigationBarOnBottom = (!mNavigationBarCanMove || displayWidth < displayHeight);//判断是否显示在底部,为true,显示在底部,false显示在右侧。

追踪到navigation bar的流程,继续往下看,哈哈,发现到statusbar方向控制的代码,我把这段代码贴下来。
// apply any navigation bar insets
pf.left = df.left = of.left = mUnrestrictedScreenLeft;
pf.top = df.top = of.top = mUnrestrictedScreenTop;
pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft;
pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight
+ mUnrestrictedScreenTop;
vf.left = mStableLeft;
vf.top = mStableTop;
vf.right = mStableRight;
vf.bottom = mStableBottom;
mStatusBarLayer = mStatusBar.getSurfaceLayer();
// Let the status bar determine its size.
mStatusBar.computeFrameLw(pf, df, vf, vf, vf, dcf, vf);

客户需求是把statusbar的方向移到右边,navigation bar的方向移动左边,这里navigation bar暂不作考虑,贴出status bar修改的代码。
static final Rect mTemStatusBarFrame=new Rect();
mTemStatusBarFrame.set(displayWidth-overscanRight-mStatusBarHeight, 0,displayWidth-overscanRight, displayHeight);
// apply any navigation bar insets
/* pf.left = df.left = of.left = mUnrestrictedScreenLeft;
pf.top = df.top = of.top = mUnrestrictedScreenTop;
pf.right = df.right = of.right = mUnrestrictedScreenWidth + mUnrestrictedScreenLeft;
pf.bottom = df.bottom = of.bottom = mUnrestrictedScreenHeight
+ mUnrestrictedScreenTop;
vf.left = mStableLeft;
vf.top = mStableTop;
vf.right = mStableRight;
vf.bottom = mStableBottom;*/
mStatusBarLayer = mStatusBar.getSurfaceLayer();
// Let the status bar determine its size.
// mStatusBar.computeFrameLw(pf, df, vf, vf, vf, dcf, vf);
mStatusBar.computeFrameLw(mTemStatusBarFrame, mTemStatusBarFrame, mTemStatusBarFrame, mTemStatusBarFrame, mTemStatusBarFrame, dcf, mTemStatusBarFrame);
当然,不是这么简单的事,其他参数的坐标值也都需要修改,例如mStableTop,mStableRight,mDockTop等参数值都需要修改,我在这里就不一一说明了,只给大家提供一个入口点。

改了statusbar的方向,接下来就是statusbar布局修改了,接下来进入到SystemUI,statusbar的布局涉及到super_status_bar.xml、status_bar.xml、status_bar_ticker.xml、system_icons.xml、signal_cluster_view.xml。statusbar是通过StatusBarWindowManager.java的add(View statusBarView, int barHeight) 画出来。
public void add(View statusBarView, int barHeight) {
// Now that the status bar window encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
mLp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
barHeight,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT);
mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
mLp.gravity = Gravity.TOP;
mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
mLp.setTitle(“StatusBar”);
mLp.packageName = mContext.getPackageName();
mStatusBarView = statusBarView;
mBarHeight = barHeight;
mWindowManager.addView(mStatusBarView, mLp);
mLpChanged = new WindowManager.LayoutParams();
mLpChanged.copyFrom(mLp);
}
修改成
public void add(View statusBarView, int barHeight) {
// Now that the status bar window encompasses the sliding panel and its
// translucent backdrop, the entire thing is made TRANSLUCENT and is
// hardware-accelerated.
mLp = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
/* barHeight,*/
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS,
PixelFormat.TRANSLUCENT);
mLp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
mLp.gravity = Gravity.RIGHT;
mLp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
mLp.setTitle(“StatusBar”);
mLp.packageName = mContext.getPackageName();
mStatusBarView = statusBarView;
mBarHeight = barHeight;
mWindowManager.addView(mStatusBarView, mLp);
mLpChanged = new WindowManager.LayoutParams();
mLpChanged.copyFrom(mLp);
}

到此,statusbar分析结束了,这只是一个简单的修改,我之前的客制化是有把下拉状态栏和通知功能都去掉了的,如果下拉状态栏和通知不去掉的话,statusbar由顶部移到两侧是行不通的。

猜你喜欢

转载自blog.csdn.net/zengrunxiu/article/details/80702664