自定义ViewGroup自实现笔记

来源:互联网 发布:移动设备数据恢复 编辑:程序博客网 时间:2024/06/05 03:39

自己写的DEMO,参照了http://blog.csdn.net/a396901990/article/details/36475213,写了一个viewgroup为了便与记忆,打印了一些参数,先试XML

<?xml version="1.0" encoding="utf-8"?><com.example.luoliang.measuredemo.MyViewGroup xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:background="#00ff00"    tools:context="com.example.luoliang.measuredemo.MainActivity">    <Button        android:id="@+id/tv"        android:layout_width="120dp"        android:layout_height="160dp"        android:padding="10dp"        android:layout_margin="30dp"        android:background="#ff0000"        android:textColor="#ffffff"        android:text="Hello World!" /></com.example.luoliang.measuredemo.MyViewGroup>
public class MyViewGroup extends ViewGroup {    private static final String TAG = MyViewGroup.class.getSimpleName() ;    private Context ctx ;    private AttributeSet attrs ;    public MyViewGroup(Context context) {        this(context,null);//        init();    }    public MyViewGroup(Context context, AttributeSet attrs) {        super(context, attrs);        this.ctx = context;        this.attrs = attrs;    }    @Override    protected LayoutParams generateDefaultLayoutParams() {        return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);    }    @Override    public LayoutParams generateLayoutParams(AttributeSet attrs) {        return new MarginLayoutParams(ctx,attrs);    }    @Override    protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) {        return new LayoutParams(p);    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        measureChildren(widthMeasureSpec,heightMeasureSpec);    }    @Override    protected void measureChildren(int widthMeasureSpec, int heightMeasureSpec) {        int mChildrenCount = getChildCount();        final int size = mChildrenCount;//        measureChildren(widthMeasureSpec,heightMeasureSpec);        for (int i=0;i<size;i++){            View view = this.getChildAt(i);            MarginLayoutParams lp = (MarginLayoutParams) view.getLayoutParams();            int width = lp.width;            int height = lp.height;            measureChild(view,widthMeasureSpec,heightMeasureSpec);//            setMeasuredDimension(width,height);        }//        super.measureChildren(widthMeasureSpec, heightMeasureSpec);    }//    @Override//    protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {//        super.measureChild(child, parentWidthMeasureSpec, parentHeightMeasureSpec);//        LayoutParams lp = child.getLayoutParams();//        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,child.getPaddingLeft()+child.getPaddingRight(),lp.width);//        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,child.getPaddingTop()+child.getPaddingBottom(),lp.height);//        child.measure(childWidthMeasureSpec,childHeightMeasureSpec);//    }//    public static int getChildMeasureSpec(int spec,int padding,int childDimension){//        int specMode = MeasureSpec.getMode(spec);//        int specSize = MeasureSpec.getSize(spec);//        int size = Math.max(0,specSize-padding);//父view建议子view用的值,但子view不一定用//        //子view想要的实际大小和模式需要计算//        int resultSize = 0;//        int resultMode = MeasureSpec.EXACTLY ;//        switch(specMode){//            case MeasureSpec.EXACTLY://                if (childDimension>0){//                    resultSize = childDimension;//                    resultMode = MeasureSpec.EXACTLY;////                }else if (childDimension==LayoutParams.MATCH_PARENT){//                    resultSize = size;//                    resultMode = MeasureSpec.EXACTLY;//                }else if(childDimension==LayoutParams.WRAP_CONTENT){//                    resultSize = size;//                    resultMode = MeasureSpec.AT_MOST;//                }//                break;//            case MeasureSpec.AT_MOST://                if (childDimension>0){//                    resultSize = childDimension;//                    resultMode = MeasureSpec.EXACTLY;////                }else if (childDimension==LayoutParams.MATCH_PARENT){//                    resultSize = size;//                    resultMode = MeasureSpec.AT_MOST;//                }else if (childDimension==LayoutParams.WRAP_CONTENT){//                    resultSize = size;//                    resultMode = MeasureSpec.AT_MOST;//                }//                break;//            case MeasureSpec.UNSPECIFIED://                if (childDimension>0){//                    resultSize = childDimension;//                    resultMode = MeasureSpec.EXACTLY;////                }else if (childDimension==LayoutParams.MATCH_PARENT){//                    resultSize = 0;//                    resultMode = MeasureSpec.UNSPECIFIED;//                }else if (childDimension==LayoutParams.WRAP_CONTENT){//                    resultSize = 0;//                    resultMode = MeasureSpec.UNSPECIFIED;//                }//                break;//        }//       return MeasureSpec.makeMeasureSpec(resultSize,resultMode);//    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        for (int i=0;i<getChildCount();i++){            View child = getChildAt(i);            MarginLayoutParams mPara = (MarginLayoutParams) child.getLayoutParams();            MarginLayoutParams mParentPara = (MarginLayoutParams) getLayoutParams();                            int width = child.getMeasuredWidth();                int height = child.getMeasuredHeight();                int mLeft = (r-width)/2;                int mTop = (r-height)/2;                DisplayMetrics dm = new DisplayMetrics();                WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);                wm.getDefaultDisplay().getMetrics(dm);                Log.d(TAG,"dm.density:"+dm.density+"child.getWidth():"+child.getWidth()+"child.getHeight():"+child.getHeight()+"child.getMeasuredWidth():"+child.getMeasuredWidth()+"child.getMeasuredHeight():"+child.getMeasuredHeight()+                        "child.getPaddingLeft():"+child.getPaddingLeft()+"child.getPaddingTop():"+child.getPaddingTop()+"child.getPaddingRight():"+child.getPaddingRight()+"child.getPaddingBottom():"+child.getPaddingBottom()+                        "child.getLeft():"+child.getLeft()+"child.getTop():"+child.getTop()+"child.getRight():"+child.getRight()+"child.getBottom():"+child.getBottom()+"mPara.topMargin:"+mPara.topMargin                        +"mPara.topMargin:"+mPara.topMargin+"mPara.rightMargin:"+mPara.rightMargin+"mPara.bottomMargin:"+mPara.bottomMargin+"mParentPara.leftMargin"+mParentPara.leftMargin                        +"mParentPara.topMargin"+mParentPara.topMargin+"mParentPara.rightMargin"+mParentPara.rightMargin+"mParentPara.bottomMargin"+mParentPara.bottomMargin);                child.layout(child.getPaddingLeft()+mPara.leftMargin,child.getPaddingTop()+mPara.topMargin,width+child.getPaddingRight()+mPara.rightMargin,mPara.bottomMargin+height+child.getPaddingBottom());//                child.layout(0,0,width+child.getPaddingRight(),height+child.getPaddingBottom());//                child.layout(child.getLeft(),child.getTop(),child.getRight(),child.getBottom());                Log.d(TAG,"child.getWidth():"+child.getWidth()+"child.getHeight():"+child.getHeight());                    }    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);    }}
12-05 02:34:34.814 23743-23743/com.example.luoliang.measuredemo D/MyViewGroup: dm.density:2.0child.getWidth():0child.getHeight():0child.getMeasuredWidth():240child.getMeasuredHeight():320child.getPaddingLeft():20child.getPaddingTop():20child.getPaddingRight():20child.getPaddingBottom():20child.getLeft():0child.getTop():0child.getRight():0child.getBottom():0mPara.topMargin:60mPara.topMargin:60mPara.rightMargin:60mPara.bottomMargin:60mParentPara.leftMargin0mParentPara.topMargin0mParentPara.rightMargin0mParentPara.bottomMargin0

12-05 02:34:34.814 23743-23743/com.example.luoliang.measuredemo D/MyViewGroup: child.getWidth():240child.getHeight():320

12-05 02:34:34.854 23743-23743/com.example.luoliang.measuredemo D/MyViewGroup: dm.density:2.0child.getWidth():240child.getHeight():320child.getMeasuredWidth():240child.getMeasuredHeight():320child.getPaddingLeft():20child.getPaddingTop():20child.getPaddingRight():20child.getPaddingBottom():20child.getLeft():80child.getTop():80child.getRight():320child.getBottom():400mPara.topMargin:60mPara.topMargin:60mPara.rightMargin:60mPara.bottomMargin:60mParentPara.leftMargin0mParentPara.topMargin0mParentPara.rightMargin0mParentPara.bottomMargin0

12-05 02:34:34.854 23743-23743/com.example.luoliang.measuredemo D/MyViewGroup: child.getWidth():240child.getHeight():320

child.layout(child.getPaddingLeft()+mPara.leftMargin,child.getPaddingTop()+mPara.topMargin,width+child.getPaddingRight()+mPara.rightMargin,mPara.bottomMargin+height+child.getPaddingBottom());
注意就是这个方法里面一定要自己设置好,左上右下,左就是child的paddingLeft+child的leftMargin,上就是child的paddingtop+child的topMargin,右就是child的paddingright+child的rightMargin,下就是child的paddingBottom+child的bottomMargin,不然出来的位置不对,我开始也是不对,我也是通过打印后面那个log才知道的,
mParentPara这个在Log里没值,应该是在遍历子view,还没有到编译自己
可以把注释的measureChild的这个方法打开,用自己写的,其实跟系统实现的是一样的


1 0