5.10. Custom Views
To customise a View, we must create a component of type: New \ UiComponent \ Custom View. If we call our view “MyView”
, a sample layout file will be created with the name sample_my_view.xml
. This file shows us how to use this view in our layout.
Meanwhile, the view is implemented in the Kotin file MyView
.
In the MyView class four properties will be created for us:
private var _exampleString: String? = null
private var _exampleColor: Int = Color.RED
private var _exampleDimension: Float = 0f
var exampleDrawable: Drawable? = null
These properties can be assigned from the layout that uses this class, as follows:
<com.uoc.layouts3.MyView
android:layout_width="200dp"
android:layout_height="200dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:exampleColor="#00FF00"
app:exampleDimension="24sp"
app:exampleDrawable="@android:drawable/ic_menu_add"
app:exampleString="Hello, MyView" />
These properties are loaded into one of the class builders using the parameter attrs
and the obtainStyledAttributes
context method:
private fun init(attrs: AttributeSet?, defStyle: Int) {
// Load attributes
val = context.obtainStyledAttributes(
attrs, R.styleable.MyView, defStyle, 0
)
_exampleString = a.getString(
R.styleable.MyView_exampleString
)
_exampleColor = a.getColor(
R.styleable.MyView_exampleColor,
exampleColor
)
}
The other method to be rewritten is the onDraw
callback. onDraw
receives the Canvas, the area that the layout has allocated. Coordinates refer to that area. This method uses canvas primitives that allow painting text, images, rectangles, lines, …
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
}
For example, to paint a rectangle we would use the following code:
val myPaint = Paint()
myPaint.setStyle(Paint.Style.FILL_AND_STROKE)
myPaint.setColor(Color.RED)
canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(),myPaint)
To paint a text, we would use:
textPaint = TextPaint().apply {
flags = Paint.ANTI_ALIAS_FLAG
textAlign = Paint.Align.LEFT
}
canvas.drawText(
it,
paddingLeft + (contentWidth - textWidth) / 2,
paddingTop + (contentHeight + textHeight) / 2,
textPaint
)
To paint an image, we would use:
var exampleDrawable: Drawable? = null
exampleDrawable = a.getDrawable(
R.styleable.MyView_exampleDrawable
)
exampleDrawable?.callback = this
exampleDrawable?.let {
it.setBounds(
paddingLeft, paddingTop,
paddingLeft + contentWidth, paddingTop + contentHeight
)
it.draw(canvas)
}