美文网首页
自定义View系列01

自定义View系列01

作者: Thor_果冻 | 来源:发表于2018-12-29 15:29 被阅读0次

    @[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()
    

    相关文章

      网友评论

          本文标题:自定义View系列01

          本文链接:https://www.haomeiwen.com/subject/msfplqtx.html