Android自定义View随笔

类别

自定义View,有三种方式,分别满足不同的需求:
  1. 扩展Android自带的View控件,在原生控件基础上扩展自己的样式和点击事件;
  2. 组合式ViewGroup,实现ViewGroup内多个子View的统一逻辑, 比如自定义顶部标题栏;
  3. 拓展View类,实现完全的自定义样式和点击事件。

基本模式

    //拓展对应的View
    public class CustomView extend View{

        //复写三个构造方法,并提供初始化的init()供初始化Paint类等
        public CustomView(Context context){
            this(context, null);
        }
        public CustomView(Context context, AttributeSet attrs){
            this(context, null, 0);
        }
        public CustomView(Context context, AttributeSet attires, int defStyleAttr){
            super(context, attrs, defStyleAttr);
            init();
        }

        private void init(){}

        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            setMeasuredDimension(width, height);
        }

        //一般是ViewGoup复写此方法,实现对子View的布局
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom) {}

        @Override
        protected void onDraw(Canvas canvas) {}

        @Override
        public boolean onTouchEvent(MotionEvent event) {}
    }

理解

  1. onMeasure方法

    onMeasure在控件测量时在Measure()中调用,实现自己的宽和高的逻辑后由setMeasuredDimension()方法将宽高设置给控件:
    Measure–>onMeasure–>自定义宽高逻辑–>setMeasuredDimension。复写onMeasure时,方法提供此控件的测量模式和经父容器测量后提供给此控件可用控件的宽高值。
    我们在设置控件的layout_with属性时,此属性虽然是在控件中设置,但是是提供给此控件所在的父布局使用的。其实可以这么理解,父布局统筹子控件的宽高属性,并将处理后的子控件宽高模拟和可用的使用空间宽高提供给子类。如果控件使用match_parent/精准值(如110dp),则指明此控件宽度根据某一值进行设置,在onMeasure中对应的测量模式是MeasureSpec.EXACTLY, 如果是wrap_content,则对应的测量模式是MeasureSpec.AT_MOST,还有一个MeasureSpec.UNSPECIFIED都说用得少,我也不清楚。
    复写此方法没实现宽高逻辑,则默认的效果是,控件可以实现填充父布局或者按指定的值显示宽高,但是无法实现wrap_content效果,这也是我们在onMeasure方法里需要自己实现的部分,其实大概模式如下(以宽为例,高度相同)

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        if (widthMode == MeasureSpec.EXACTLY) {
            width = widthSize;
        } else {
            //targetSize根据控件要求可以是一个默认的宽度或者是控件自身的宽度
            if(widthMode == MeasureSpec.AT_MOST){
             width = Min(widthSize, targetSize);
            }
    
        }
    
  2. onDraw方法

    基本的思路是,通过对点击事件和其他事件的响应,通过invalidate()方法来触发控件再次调用onDraw()方法,并且控制方法里变量的值来实现控件绘制的图形对不同事件的变化。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值