首先需要了解幾個概念:
Activity:基本頁面單元 Activity包含一個Window 上面可以繪制各種view
view:最基本ui組件 表示屏幕上的一個矩形區域
Window:表示頂層窗口 管理界面的顯示和事件的響應 每一個activity都會創建一個
PhoneWindow對象:是activity和整個view系統交互的接口
phonewindow類繼承于window類 同事phonewindow類內部包含了一個DecorVie對象
相當于phoneWindow是把一個FrameLayout進行了一定的包裝 并提供了一組通用的窗口操作接口
DecorView:是window中view的rootview設置窗口屬性 是FrameLayout的子類
并且是PhoneWindow的一個內部類 DecorView(修飾類)就是對普通的FrameLayout進行了一定的修飾
比如添加一個通用的titlebar并且響應特定的按鍵消息
ViewRoot:并不是一個view類型 而是一個Handler
主要作用:
向DecorView分發收到的用戶發起的event事件 按鍵 觸屏等事件
與windowmanagerservice交互 完成整個Activity 的gui繪制
整個view的繪制流程是在viewroot類的performTraversals()函數展開的 執行過程:
根據之前設置的轉臺 判斷是否需要重新計算視圖大小 measure 是否需要重新安置視圖的位置layout
以及是否需要重新繪制draw
自定義ViewGroup
public class MyViewGroup extends ViewGroup{
public MyViewGroup(Context context){}
public MyViewGroup(Context context,AttributeSet attr){}
onMeasure(int widthMeasureSpec, int heightMeasureSpe){
int childCount = getchildCount();
//獲取ViewGroup實際的寬度和長度 涉及到MeasureSpec類的使用
int specWidth = MeasureSpec.getSize(widthMeasureSpec);
int specHeight = MeasureSpec.getSize(heigthMeasureSpe);
//設置本ViewGroup寬高、
setMeasureDimension(specWidth,specHeigth);
//設置每一個子view
for(int i=0;i<childCount;i++){
View child = getChildAt(i);
child.measure(80,80);//設置寬高
}
onLayout(boolean changed,int l,int t,int r,int b){
int childCount = getChildCount();
int startLeft= 0;
int startTop =10;
for(int i=0;iKchildCount;i++){
View child = getChildAt(i);//獲得每一個對象引用
child.layout(l,t,r,b);
startLeft =startLeft+child.getMeasuredWidth() + 10; //校準startLeft值,View之間的間距設為10px ;
}
}
dispatchDraw(Canvas canvas){}
drawChild(Canvas can,View child,long drawtime);
}
}
自定義View類型 MyView 重寫onDraw()方法
public class MyView extends View{
PRivate Paint paint = new Paint();
MyView(Context context){}
protected void onMeasure(int width,int height){
//設置view大小
setMeasureDimension(80,80);
}
//存在canvas對象 存在默然顯示區域
onDraw(Canvas canvas){
paint.setColor(Color.RED);
canvas.drawColor(Color.BLUE);//view的背景色
canvas.drawRect(0.0,30,30,paint);//繪制矩形
canvas.drawText("MyView",10,40,paint);
}
}
詳情請參照:點擊打開鏈接
新聞熱點
疑難解答