自定义View系列01

2018-12-29  本文已影响0人  Thor_果冻

@[toc]

自定义View系列01

简单理解

构造方法

/**
* new的时候调用
*/
constructor(context: Context) : this(context, null)

/**
* 在布局layout中使用(调用)
*/
constructor(context: Context, @Nullable attrs: AttributeSet?) : this(context, attrs, 0)

/**
* 在布局layout中使用,但是会有style(比如在布局中使用style=@style/xxx)
*/
constructor(context: Context, @Nullable attrs: AttributeSet?, defStyleAttr: Int): super(context, attrs, defStyleAttr)

onMeasure方法

    /**
     * 测量方法
     * 布局的宽高都是在这里指定
     */
    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        //获取宽高模式,wrap_content
        val widthMode = MeasureSpec.getMode(widthMeasureSpec)//获取32位数中前2位
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        val widthSize = MeasureSpec.getSize(widthMeasureSpec)//获取32位数中的后30位
        val heightSize = MeasureSpec.getSize(heightMeasureSpec)

        when (heightMode) {
            MeasureSpec.AT_MOST -> {
                //在布局中指定了wrap_content
            }
            MeasureSpec.EXACTLY -> {
                //在布局中指定了确定的值match_parent,100dp
            }
            MeasureSpec.UNSPECIFIED -> {
                //尽可能地大,这种很少用到,但是系统由用到如listView,ScrollView
                /*
                    比如我们以前用的ScrollView嵌套ListView中显示不全问题,是因为ListView,ScrollView在测量子布局
                    的时候会用MeasureSpec.UNSPECIFIED这种模式,所以我们只要自定义其子布局重新定义其onMeasure方法就好了
                    比如现在的只要自定义ListView重写OnMeasure方法然后再其super上添加
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE >> 2, MeasureSpec.AT_MOST)
                    heightMeasureSpec = MeasureSpec.makeMeasureSpec(Int.MAX_VALUE shr 2, MeasureSpec.AT_MOST)
                    为什么最大值右移2为:因为一个32位的数 前2位为模式,后30位为数值
                 */
            }
        }
    }

OnDraw方法

    /**
     * 绘制方法
     */
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        with(canvas){
            //文本
            //drawText()
            //弧
            //drawArc()
            //圆
            //drawCircle()
        }
    }

onTouchEvent

    /**
     * 处理事件分发
     */
    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent): Boolean {
        when(event.action){
            MotionEvent.ACTION_UP ->{
                //抬起
            }
            MotionEvent.ACTION_MOVE ->{
                //移动
            }
            MotionEvent.ACTION_DOWN ->{
                //按下
            }
        }
        return super.onTouchEvent(event)
    }

自定义属性

android中自定义属性格式详解

在res中的values中创建一个attrs.xml文件,里面添加自定义属性

获取自定义属性

        //获取自定义属性
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.xxx)//R.styleable.xxx自定义style名称
        val id_str = typedArray.getString(R.styleable.id_xxx)//styel中id名称
        
        //回收
        typedArray.recycle()
上一篇下一篇

猜你喜欢

热点阅读