Android 自定义View一

1.继承已有VIew,改写尺寸:重写onMeasure

  SquareImageView

2.完全自定义重写onMeasure

3.自定义Layout 重写onMeasure onLayout

1.继承已有VIew,改写尺寸:重写onMeasure

流程:

重写onMeasure

用getmeasureedWidth getMeasuredHeight获取测量尺寸

计算最终尺寸

setMeasuredDissmension(w,h)保存结果

getMeasuredWidth getMeasuredHeight 测量期望尺寸,在测量过程中使用(提前取)

getWidth = right -left, geiHeight = bottom-top 实际尺寸,在非测量过程使用(更准确)

onMeasure 测量 根据自身测量和父VIew约束进行判断 ATMODE EX.....

val width = when(specMode) {
    MeasureSpec.EXACTLY -> specSize//精确
    MeasureSpec.AT_MOST -> if ( size > specSize) specSize else size//约束,大于
    else -> size //不限制
}

在kotlin 等同于下面写法,更加简洁
val width1 = resolveSize(size,widthMeasureSpec)

resolveSize 、 resolveSizeAndState  区别: 结果是一样的

还有 resolveSizeAndState  在进行自身测量和父布局给出的大小不一致时,会标记SALL,MASK,然后给父VIew一个值,父VIew会拿到结果进行重新测量

tips:很多系统ViewGroup大多数不会去读resolveSizeAndState 的TO_SMALL 等标志位

源码:

package com.example.myapplication.view

import android.content.Context
import android.util.AttributeSet
import android.widget.ImageView
import androidx.appcompat.widget.AppCompatImageView
import kotlin.math.min

class SquareImageView(context : Context,attributeSet: AttributeSet) : AppCompatImageView(context,attributeSet){



//    override fun layout(l: Int, t: Int, r: Int, b: Int) {
//
//        val width = r-l
//        val height = b-t
//        val size = min(width,height)
//        super.layout(l, t, l+size, t+size)
//    }



    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val size = min(measuredWidth,measuredHeight)
        setMeasuredDimension(size,size)
    }
}

package com.example.myapplication.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View

class CircleView(context: Context,attributeSet: AttributeSet) :View(context,attributeSet) {
   private var paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private val RADIUS = 300f
    private val PADING = 300f


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        val size = ((PADING + RADIUS) * 2).toInt()
       val specMode =  MeasureSpec.getMode(widthMeasureSpec)
        val specSize = MeasureSpec.getSize(widthMeasureSpec)


        val width = when(specMode) {
            MeasureSpec.EXACTLY -> specSize//精确
            MeasureSpec.AT_MOST -> if ( size > specSize) specSize else size//约束,大于
            else -> size //不限制
        }

        val width1 = resolveSize(size,widthMeasureSpec)
        val height1 = resolveSize(size,heightMeasureSpec)

        setMeasuredDimension(width1,height1)
    }
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawCircle(PADING + RADIUS,PADING + RADIUS,RADIUS,paint)

    }
}

你可能感兴趣的:(android)