自定義viewgroup 及view--簡單描述

原文地址:http://blog.csdn.net/qinjuning/article/details/7110211

1.自定義ViewGroup

      //自定義ViewGroup 對象  
    public class MyViewGroup  extends ViewGroup{  


        private static String TAG = "MyViewGroup" ;  
        private Context mContext ;  

        public MyViewGroup(Context context) {  
            super(context);  
            mContext = context ;  
            init() ;  
        }  

        //xml定義的屬性,需要該構造函數  
        public MyViewGroup(Context context , AttributeSet attrs){  
            super(context,attrs) ;  
            mContext = context ;  
            init() ;  
        }  

        //爲MyViewGroup添加三個子View  
        private void init(){  
            //調用ViewGroup父類addView()方法添加子View  

            //child 對象一 : Button  
            Button btn= new Button(mContext) ;  
            btn.setText("I am Button") ;  
            this.addView(btn) ;  

            //child 對象二 : ImageView   
            ImageView img = new ImageView(mContext) ;  
            img.setBackgroundResource(R.drawable.icon) ;  
            this.addView(img) ;  

            //child 對象三 : TextView  
            TextView txt = new TextView(mContext) ;  
            txt.setText("Only Text") ;  
            this.addView(txt) ;   

            //child 對象四 : 自定義View  
            MyView myView = new MyView(mContext) ;  
            this.addView(myView) ;   
        }  

        @Override  
        //對每個子View進行measure():設置每子View的大小,即實際寬和高  
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){  
            //通過init()方法,我們爲該ViewGroup對象添加了三個視圖 , Button、 ImageView、TextView  
            int childCount = getChildCount() ;  
            Log.i(TAG, "the size of this ViewGroup is ----> " + childCount) ;  

            Log.i(TAG, "**** onMeasure start *****") ;  

            //獲取該ViewGroup的實際長和寬  涉及到MeasureSpec類的使用  
            int specSize_Widht = MeasureSpec.getSize(widthMeasureSpec) ;  
            int specSize_Heigth = MeasureSpec.getSize(heightMeasureSpec) ;  

            Log.i(TAG, "**** specSize_Widht " + specSize_Widht+ " * specSize_Heigth   *****" + specSize_Heigth) ;  

            //設置本ViewGroup的寬高  
            setMeasuredDimension(specSize_Widht , specSize_Heigth) ;  




            for(int i=0 ;i<childCount ; i++){  
                View child = getChildAt(i) ;   //獲得每個對象的引用  
                child.measure(50, 50) ;   //簡單的設置每個子View對象的寬高爲 50px , 50px    
                //或者可以調用ViewGroup父類方法measureChild()或者measureChildWithMargins()方法  
                //this.measureChild(child, widthMeasureSpec, heightMeasureSpec) ;  
            }  

        }  

        @Override  
        //對每個子View視圖進行佈局  
        protected void onLayout(boolean changed, int l, int t, int r, int b) {  
            // TODO Auto-generated method stub  
            //通過init()方法,我們爲該ViewGroup對象添加了三個視圖 , Button、 ImageView、TextView  
            int childCount = getChildCount() ;  

            int startLeft = 0 ;//設置每個子View的起始橫座標   
            int startTop = 10 ; //每個子View距離父視圖的位置 , 簡單設置爲10px吧 。 可以理解爲 android:margin=10px ;  

            Log.i(TAG, "**** onLayout start ****") ;  
            for(int i=0 ;i<childCount ; i++){  
                View child = getChildAt(i) ;   //獲得每個對象的引用  
                child.layout(startLeft, startTop, startLeft+child.getMeasuredWidth(), startTop+child.getMeasuredHeight()) ;  
                startLeft =startLeft+child.getMeasuredWidth() + 10;  //校準startLeft值,View之間的間距設爲10px ;  
                Log.i(TAG, "**** onLayout startLeft ****" +startLeft) ;  
            }             
        }  
        //繪圖過程Android已經爲我們封裝好了 ,這兒只爲了觀察方法調用程  
        protected void dispatchDraw(Canvas canvas){  
            Log.i(TAG, "**** dispatchDraw start ****") ;  

            super.dispatchDraw(canvas) ;  
        }  

        protected boolean drawChild(Canvas canvas , View child, long drawingTime){  
            Log.i(TAG, "**** drawChild start ****") ;  

            return super.drawChild(canvas, child, drawingTime) ;  
        }  
    }  

2.自定義View

主要是重寫onDraw()方法 ,


    //自定義View對象  
        public class MyView extends View{  

            private Paint paint  = new Paint() ;  

            public MyView(Context context) {  
                super(context);  
                // TODO Auto-generated constructor stub  
            }  
            public MyView(Context context , AttributeSet attrs){  
                super(context,attrs);  
            }  

            protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){  
                //設置該View大小爲 80 80  
                setMeasuredDimension(50 , 50) ;  
            }  



            //存在canvas對象,即存在默認的顯示區域  
            @Override  
            public void onDraw(Canvas canvas) {  
                // TODO Auto-generated method stub  
                super.onDraw(canvas);  

                Log.i("MyViewGroup", "MyView is onDraw ") ;  
                //加粗  
                paint.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD));  
                paint.setColor(Color.RED);  
                canvas.drawColor(Color.BLUE) ;  
                canvas.drawRect(0, 0, 30, 30, paint);  
                canvas.drawText("MyView", 10, 40, paint);  
            }  
        }  

主Activity只是顯示了該xml文件,在此也不羅嗦了。 大家可以查看該ViewGroup的Log仔細分析下View的繪製流程以及相關方法的使用。第一次啓動後捕獲的Log如下,網上找了些資料,第一次View樹繪製過程會走幾遍,具體原因可能是某些View 發生了改變,請求重新繪製,但這根本不影響我們的界面顯示效果 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章