4.3
首先学习下窗口管理:http://blog.csdn.net/luoshengyang/article/details/8479101
一:
1>:
在新增和删除了窗口、窗口动画显示过程、窗口切换过程中,Activity窗口在其属性发生了变化,例如,可见性、大小发生了变化,又或者它新增、删除了子视图,都需要重新计算大小,这些都需要WindowManagerService服务都不断地刷新系统的UI。
成员函数performLayoutAndPlaceSurfacesLocked来主要的功能是用来刷新系统的UI,计算Activity窗口的大小:
WindowManagerService .java
private final void performLayoutAndPlaceSurfacesLocked(){
。。。
performLayoutAndPlaceSurfacesLockedLoop();
。。。
}
2>:
WindowManagerService .java
private final void performLayoutAndPlaceSurfacesLockedLoop(){
。。。。
performLayoutAndPlaceSurfacesLockedInner(recoveringMemory);
。。。。
}
3>:
public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor,WindowManagerPolicy.WindowManagerFuncs,
DisplayManagerService.WindowManagerFuncs,DisplayManager.DisplayListener{
。。。。。。。。。
performLayoutAndPlaceSurfacesLockedInner(boolean recoveringMemory){
......
displayContent.pendingLayoutChanges |= mPolicy.finishPostLayoutPolicyLw();
....
}
。。。。。。。。
}
实际----> public interface WindowManagerPolicy {
public int finishPostLayoutPolicyLw();
}
4>:控制状态栏是否隐藏
public class PhoneWindowManager implements WindowManagerPolicy{
.....
public int finishPostLayoutPolicyLw() {
...
if (mStatusBar != null) {
if (mForceStatusBar || mForceStatusBarFromKeyguard){
.....
}else if (mTopFullscreenOpaqueWindowState != null){
topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0 || (mLastSystemUiFlags & View.SYSTEM_UI_FLAG_FULLSCREEN)!=0;
if(topIsFullscreen){
//HIDING status bar
.......
}else{
//SHOWING status bar: top is not fullscreen
........
}
}
}
......
}
......
}
二:TpPatch
TP不灵敏会导致状态栏下拉不灵敏,解决思路:
扩展状态栏相应区域;方法:在状态栏view下做一个悬浮的与状态栏等宽,高度为几个像素(不影响其他界面的view事件前提下所设置的悬浮高度)的view,让该view拥有状态栏的触摸下拉事件。
1>:添加view
private void addStatusBarWindow(){
。。。。。
makeStatusBarView();
mWindowManager.addView(mStatusBarWindow, lp);
//开始添加
final int heightTp = 8;
final WindowManager.LayoutParams tpPatch = new WindowManager.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
heightTp ,
WindowManager.LayoutParams.TYPE_PHONE,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
PixelFormat.TRANSLUCENT);
);
tpPatch.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
mWindowManager.addView(mTpPatchView, tpPatch);
}
2>:实现view事件处理
(1)下拉事件
mTpPatchView = new TextView(mContext);
mTpPatchView.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
animateExpandNotificationsPanel();//调用整个下拉栏下拉
return true;
}});
mStatusBarView.setTpPatch(mTpPatchView);
(2)全屏与非全屏切换时view同状态栏一起消失、出现事件
前面提到状态栏的隐藏与出现控制在PhoneWindowManager.java
先看结果:
//HIDING status bar
.......
try{
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
statusbar.fullScreenPatch(true);
}
}catch (RemoteException ex){
mStatusBarService = null;
}
//SHOWING status bar: top is not fullscreen
........
try{
IStatusBarService statusbar = getStatusBarService();
if (statusbar != null) {
statusbar.fullScreenPatch(false);
}
}catch (RemoteException ex){
mStatusBarService = null;
}
}
另外:
【1】:通过 IStatusBarService.aidl中定义
void fullScreenPatch(boolean state);
在
public class StatusBarManagerService extends IStatusBarService.Stub implements WindowManagerService.OnHardKeyboardStatusChangeListener{
public void fullScreenPatch(boolean state){
enforceExpandStatusBar();
if (mBar != null) {
try{
mBar.fullScreenPatch(state);
}catch (RemoteException ex){
}
}
}
}实现。
【2】然后通过在IStatus.aidl中定义
void fullScreenPatch(boolean state);
在CommandQueue.java里实现(CommandQueue extends IStatusBar.Stub)
public void fullScreenPatch(boolean state){
synchronized (mList) {
mHandler.removeMessages(MSG_SET_FULL_SCREEN_STATE);
mHandler.obtainMessage(MSG_SET_FULL_SCREEN_STATE, state ? 1 : 0, 0,
null).sendToTarget();
}
}
【3】接着消息推送:
CommandQueue.java
private final class H extends Handler{
public void handleMessage(Message msg){
final int what = msg.what & MSG_MASK;
switch (what) {
。。。
case MSG_SET_FULL_SCREEN_STATE:
mCallbacks.setFullScreenState(msg.arg1 != 0);
break;
}
}
}
【4】:CommandQueue.java
public interface Callbacks {
。。。
public void setFullScreenState(boolean state);
}
实现在:PhoneStatusBar.java
public void setFullScreenState(boolean state){
if(!state){
if(mTpPatchView.getVisibility() != View.VISIBLE){
mTpPatchView.setVisibility(View.VISIBLE);
}
}else{
if(mTpPatchView !=null){
mTpPatchView.setVisibility(View.GONE);
}
}
}
注:
1、BaseStatusBar.java
2、PanelBar.java
public void setTpPatch(View v){
mTpPatchView = v;
}
3、 private static final int MSG_SET_FULL_SCREEN_STATE= 17 << 0xfffff;