自定义view android群英传笔记

Android控件架构

这里写图片描述

  • ViewGroup控件可以包含多个view控件,并管理其包含的View 控件
    上层控件负责下层控件的测量与绘制,并传递交互事件。
  • DecorView 包括TitleView 和ContentView
    • ContentView :一个id为content 的Framelayout,
      activity_main.xml就是设置在这样的一个Framelayout里。
    • 当程序在onCreat()方法中调用stContentView()方法后ActivityManagerService会回调onResume()方法,此时系统才会把整个DecorView添加到PhoneView中 并让其显示出来,从而完成界面绘制。

自定义View

view 的测量 onMeasure()

重写此方法的目的就是为了给view一个wrap_content属性 下的默认大小。
* 三种模式:

EXACTLY: 精确值模式 指定数值或者是match_parent。
AT_MOST: wrap_content 此时控件的尺寸只要不超过父控件允许的最大尺寸即可。
UNSPECIFIED: 不指定其大小测量模式,view想多大就多大。

  • 重写onMeasuer的模板代码:
  @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
       setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));

    }

    /**
     * 测量宽
     * MeasureSpec 是一个32位int值,高2位是测量模式,低30位是测量的大小
     * @param widthMeasureSpec
     * @return
     */
    private int measureWidth(int widthMeasureSpec ){
        int  result=0;
        int specMode=MeasureSpec.getMode(widthMeasureSpec);//获取模式
        int specSize=MeasureSpec.getSize(widthMeasureSpec);
        if(specMode==MeasureSpec.EXACTLY){//精准模式
            result=specSize;
        }else {
            result=200;
            if(specMode==MeasureSpec.AT_MOST){
                result=Math.min(result,specSize);//如果是最大值模式(最大不能超过多少)   取最小值
            }
        }
        return  result;
    }
    private int measureHeight(int heightMeasureSpec ){
        int result;
        int mode = MeasureSpec.getMode(heightMeasureSpec);
        int size = MeasureSpec.getSize(heightMeasureSpec);
        if(mode==MeasureSpec.EXACTLY){
            result=size;
        }else {
            result=200;
            if(mode==MeasureSpec.AT_MOST){
                result=Math.min(result,size);
            }
        }
        return  result;
    }

view 的绘制 onDraw()

画一个简单的圆

  @Override
    protected void onDraw(Canvas canvas) {
        Paint paint=new Paint();
        paint.setColor(Color.YELLOW);
        paint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(getMeasuredWidth()/2,getMeasuredHeight()/2,Math.min(getMeasuredHeight()/2,getMeasuredWidth()/2),paint);
        super.onDraw(canvas);
    }

自定义ViewGroup

  • viewgroup获取管理其子view,当属性为wrap_content时,viewgroup就需要对子view进行遍历,以便获得所有子view的大小(调用子view的measure方法获得每一个view的测量结果),从而决定自己的大小,而在其他模式下则会通过具体 的指定值来设置自身的大小。
  @Override
    protected void onMeasure(int widthMeasureSpec,
                             int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int count = getChildCount();
        for (int i = 0; i < count; ++i) {
            View childView = getChildAt(i);
            measureChild(childView,
                    widthMeasureSpec, heightMeasureSpec);
        }
    }
  • onLayout()方法,将子view 放到合适位置。同样是使用遍历来调用子view 的layout方法,并指定其显示的具体的位置,从而来决定其布局位置。
  @Override
    protected void onLayout(boolean changed,
                            int l, int t, int r, int b) {
        int childCount = getChildCount();
        // 设置ViewGroup的高度
        MarginLayoutParams mlp = (MarginLayoutParams) getLayoutParams();
        mlp.height = mScreenHeight * childCount;
        setLayoutParams(mlp);
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child.getVisibility() != View.GONE) {
                child.layout(l, i * mScreenHeight,
                        r, (i + 1) * mScreenHeight);
            }
        }
    }

自定义属性


  • res/values/attrs.xml

<declare-styleable name="ProgressView">
    <attr name="textContent" format="string"/>
</declare-styleable>
  • 布局中使用
    xmlns:app=”http://schemas.android.com/apk/res-auto”

    app:textContent=”“
  • 获取属性
  •   // 通过这个方法,将你在atts.xml中定义的declare-styleable
            // 的所有属性的值存储到TypedArray中
            TypedArray typedArray=context.obtainStyledAttributes(attrs,R.styleable.TopBar);
            //从TypedArray中取出对应的值来为要设置的属性赋值
            mTitle = typedArray.getString(R.styleable.TopBar_mtitle);
            mTitleTextColor = typedArray.getColor(R.styleable.TopBar_mtitleTextColor,0);
            mTitleTextSize = typedArray.getDimension(R.styleable.TopBar_mtitleTextSize, 0);

    示例代码

    链接:http://pan.baidu.com/s/1qYGMwS8 密码:y4wr

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值