When I use R.styleable in a custom view class, I get a red Unresolved reference: styleable

Viewed 1420

I am a beginner. I have started learning custom views these days, and there are almost no problems in the process.

When I went to Google to solve this problem, some people proposed solutions, but none of them was successful. I use a custom view written by Kotlin.

This is my custom view class,and the name is MyView.kt

package com.example.demos

import android.R
import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import kotlin.math.min


class MyView : View {
    //    init
    private lateinit var arcPaint: Paint
    private lateinit var progressTextPaint: Paint
//    private lateinit var arcPaintColor: Color
    private var arcPaintColor = Color.BLACK
//    private lateinit var progressTextPaintColor: Color
    private var progressTextPaintColor = Color.BLACK
    private var angle = 0f
    private var progress: Float = angle / 3.6f


    //    get/set
    fun setArcPaintColor(color: Int) {
        arcPaintColor = color
    }

    fun getArcPaintColor(): Int {
        return arcPaintColor
    }

    fun setProgressTextPaintColor(color: Int) {
        progressTextPaintColor = color
    }

    fun getProgressTextPaintColor(): Int {
        return progressTextPaintColor
    }

    fun setAngle(float: Float) {
        angle = float
        progress = angle / 3.6f
        invalidate()
    }

    fun getAngle(): Float {
        return angle
    }

    fun setProgress(float: Float) {
        progress = float
        angle = progress * 3.6f
        invalidate()
    }

    fun getProgress(): Float {
        return progress
    }

    /*call method initPaint()*/
    constructor(context: Context) : super(context) {
        initPaint()
    }

    constructor(context: Context, attributeSet: AttributeSet?) : super(context, attributeSet) {
        initPaint()
    }

    constructor(context: Context, attributeSet: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attributeSet,
        defStyleAttr
    ) {
        arcPaintColor = typedArray.getColor(R.styleable.arcPaintColor,)
        initPaint()
    }


    /*override onDraw(),draw view*/
    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        drawView(canvas)
    }

    //init paints
    private fun initPaint() {
        arcPaint = Paint(Paint.ANTI_ALIAS_FLAG).also {
            it.color = arcPaintColor
            it.strokeWidth = 5f
            it.strokeWidth = 40f
            it.style = Paint.Style.STROKE
            it.strokeCap = Paint.Cap.ROUND
        }
        progressTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).also {
            it.color = progressTextPaintColor
//            it.color = Color.GREEN
//            it.setStrokeWidth(5f)
            it.style = Paint.Style.FILL
            it.textSize = 50f
        }
    }

    /*draw view*/
    private fun drawView(canvas: Canvas?) {
        val displayWidth = width
        val displayHeight = height
        /*get center of circle*/
        val centerX = (displayWidth / 2).toFloat()
        val centerY = (displayHeight / 2).toFloat()

        /*get radius*/
        val radius = min(displayWidth, displayHeight) / 4


        val rectF = RectF(
            centerX - radius,
            centerY - radius,
            centerX + radius,
            centerY + radius
        )


        canvas?.drawArc(
            rectF,
            0f,
            angle,
            false,
            arcPaint
        )

        canvas?.drawText(
            "${String.format("%.1f", progress)}%",
            centerX - progressTextPaint.measureText("${String.format("%.1f", progress)}%") / 2,
            centerY,
            progressTextPaint
        )
    }
}

This is my xml file of custom attributes

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="MyView">
        <attr name="arcPaintColor" format="color"/>
        <attr name="progressTextPaintColor" format="color"/>
    </declare-styleable>
</resources>

the xml file of my custom attribute

2 Answers

The issue is that you are importing android.R

You need to import the [you package name].R version instead.

You are not picking up the custom attributes correctly. This is how it should be done:

val typedArray =
    context.theme.obtainStyledAttributes(
        attributeSet, R.styleable.MyView, 0, 0
    )
arcPaintColor = typedArray.getColor(R.styleable.MyView_arcPaintColor, 0)
typedArray.recycle() // Important!
initPaint()

You will have to make sure that this code executes in each of your constructors. The first zero will be replace by defStyleAttr when that is available. I suggest that you integrate the above code into initPaint().

See the documentation for obtainStyledAttributes().

Related