通过网上查资料,自己看源码及加log打印调试得出的结论如下
1.android所有的可视的界面可以分为activity,dialog,poupwindow,toast,windowview
2.所有的view在显示和隐藏时都会走系统的统一的接口,并且在系统的接口中是加处理是可以拿到view的宽高,及所在的位置坐标值
3.所有view在显示前都会执行WindowManager.addView(View view, ViewGroup.LayoutParams params),隐藏的时候都会走WindowManager.removeView(View view)
------
具体调试代码及log分析如下
1.系统addview的流程如下
WindowManager.addView(View view, ViewGroup.LayoutParams params)
-----
frameworks\base\core\java\android\view\ViewManager.java
public interface ViewManager{
public void addView(View view, ViewGroup.LayoutParams params);
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
public void removeView(View view);
}
-------
frameworks\base\core\java\android\view\WindowManagerImpl.java
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
applyDefaultToken(params);
mGlobal.addView(view, params, mDisplay, mParentWindow);
}
----------
frameworks\base\core\java\android\view\WindowManagerGlobal.java
WindowManager.LayoutParams参数说明
type:用于区分所有view的类型,应用Window(及activity,dialog类)取值范围为1~99,子Window(即PoupWindow类)取值范围为1000~1999,
系统window(即windowview类型)
x,y:所在坐标值,实际受grivity参数影响
grivity:布局位置属性,如Gravity.LEFT | Gravity.TOP,Gravity.RIGHT | Gravity.TOP,grivity和x,y共同决定view所在屏幕中的位置
width,height:如果不是WindowManager.LayoutParams.WRAP_CONTENT则可以通过此参数拿到view的宽高值,如果是MATCH_PARENT类型则是屏幕的整屏参数值,如果是WRAP_CONTENT参数类型的则需要在view绘制即将完成的时候去拿view的宽高
view.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
view.getViewTreeObserver().removeOnPreDrawListener(this);
int wid = view.getWidth()