Android自定义控件入门 01 onMeasure,onDraw,自定义属性

156 阅读1分钟

1.自定义View简介

自定义View可以认为继承自Vew,系统没有的效果(ImageView,TextView,Button),extends View,extends ViewGroup,自定义一个系统的TextView.

class TextView : View {  
  
/**  
* 代码里new时调用  
* */  
constructor(context: Context) : this(context, null)  
  
/**  
* 在布局中使用  
* */  
constructor(context: Context, attrs: AttributeSet) : this(context, attrs)  
  
/**  
* 在布局中使用,会有style="@style/default"  
* */  
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs,defStyleAttr) 
}

2.onMeasure()

获取前2位

//获取宽高的模式  
val widthMode = MeasureSpec.getMode(widthMeasureSpec)  
val heightMode = MeasureSpec.getMode(heightMeasureSpec)

三种模式:MeasureSpec.EXACTLYMeasureSpec.AT_MOSTMeasureSpec.UNSPECIFIED

获取后30位

//获取宽高的值  
val heightSize = MeasureSpec.getSize(heightMeasureSpec)  
val widthSize = MeasureSpec.getSize(widthMeasureSpec)

ScrollView 嵌套ListView会显示不全问题死去的记忆突然攻击我 - 掘金 (juejin.cn)

3.onDraw()

/**  
* 用于绘制  
* */
override fun onDraw(canvas: Canvas) {  
    super.onDraw(canvas)  
    //画弧  
    canvas.drawArc()  
    //画圆  
    canvas.drawCircle()  
    //画文本  
    canvas.drawText()  
}

4.onTouch()

/**  
* 处理和用户交互的,手指触摸等  
* @param event 事件分发与拦截  
* */  
override fun onTouchEvent(event: MotionEvent): Boolean {  
    when (event.action) {  
        MotionEvent.ACTION_DOWN -> {}  
        MotionEvent.ACTION_MOVE -> {}  
    }  
    return super.onTouchEvent(event)  
}

5.自定义属性

自定义属性就是用来配置的,android:text="parren"是系统的一个自定义属性

5.1 在res下的values下面新建attrs.xml

<?xml version="1.0" encoding="utf-8"?>  
<resources>  
  
<!-- 名字最好是自定义控件 的名字-->  
    <declare-styleable name="TextView">  
    <!--  
    name属性名称  
    format格式  
        string 文字  
        color 颜色  
        dimension 宽高,字体大小  
        integer数字  
        reference资源(drawable)  
    -->  
    <attr name="darrenText" format="string" />  
    <attr name="darrenTextColor" format="color" />  
    <attr name="darrenTextSize" format="dimension" />  
    <attr name="darrenMaxLength" format="integer" />  
    <!-- 枚举-->  
    <attr name="darrenInputType">  
    <enum name="number" value="1" />  
    <enum name="text" value="2" />  
    <enum name="password" value="3" />  
    </attr>  
    </declare-styleable>  
</resources>

自定义属性名称不能与已有系统控件属性名相同!!!

5.2 在布局中使用

声明命名空间,然后在自己的自定义View中使用

xmlns:app="http://schemas.android.com/apk/res-auto"

<com.example.myapplication.TextView  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"  
    app:darrenText="darren"  
    app:darrenTextColor="#ffcc00"  
    app:darrenTextSize="25sp"  
    app:layout_constraintBottom_toBottomOf="parent"  
    app:layout_constraintEnd_toEndOf="parent"  
    app:layout_constraintStart_toStartOf="parent"  
    app:layout_constraintTop_toTopOf="parent" 
/>

5.3 在自定义View中获取属性

constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {  
    //获取自定义属性  
    val array = context.obtainStyledAttributes(attrs, R.styleable.TextView)  
    text = array.getString(R.styleable.TextView_text).toString()  
    textColor = array.getColor(R.styleable.TextView_textColor, textColor)  
    textSize = array.getDimensionPixelSize(R.styleable.TextView_textSize, textSize)  
    //回收  
    array.recycle()  
}