Пользовательский вид не отображается в Android

Я реализую пользовательскую кнопку для моего приложения для Android, где должен быть только незаполненный круг. Я относительно новичок в этой области разработки Android, поэтому у меня возникли проблемы с этим.

Есть пользовательские атрибуты:

<resources> <declare-styleable name="CircleButton"> <attr name="stroke_width" format="dimension"/> </declare-styleable> 

Код класса:

 class CircleButton (context: Context, attrs: AttributeSet) : View(context, attrs) { val paint: Paint = Paint() init { var a = context.theme.obtainStyledAttributes(attrs, R.styleable.CircleButton, 0, 0) paint.color = Color.RED try { paint.strokeWidth = a.getDimension(R.styleable.CircleButton_stroke_width, 3f) } finally { a.recycle() } } var centerX = x + width / 2 var centerY = y + height / 2 var radius = width / 2 override fun onDraw(canvas: Canvas) { super.onDraw(canvas) canvas.drawCircle(centerX.toFloat(), centerY.toFloat(), radius.toFloat(), paint) } override fun onMeasure(w : Int, h : Int) { setMeasuredDimension(w, w) } 

Это Котлин, но я думаю, все ясно. Но в любом случае я могу предоставить Java-код, если это необходимо.

Есть формат XML:

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" xmlns:custom="http://schemas.android.com/apk/res-auto" android:paddingLeft="0dp" android:paddingRight="0dp" android:paddingTop="0dp" android:paddingBottom="@dimen/activity_vertical_margin"> <com.prox1mity.myapplication.CircleButton android:layout_width="250dp" android:layout_height="300dp" android:layout_centerInParent="true" custom:stroke_width="3dp" /> 

Когда я запускаю приложение, я вижу только белый экран, а это значит, что метод onDraw работает неправильно. Но если я canvas.drawColor() рисование круга, чтобы просто заполнить холст цветом с помощью canvas.drawColor() , все в порядке, представление полностью заполнено. Это заставляет меня думать, что что-то не так с моим классом Paint или моим неправильным пониманием системы координат. Как правильно нарисовать круг с центром в центре обзора?

     var centerX = x + width / 2 var centerY = y + height / 2 var radius = width / 2 

    Этот код будет оцениваться при инициализации экземпляра. И в этот момент width = 0 и height = 0. Поскольку вид еще не измерен.

    Вы можете добавить Log.d(...) или onDraw останова в onDraw и вы увидите, что radius = 0.

    Для быстрого теста вы можете изменить onDraw на:

     override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val centerX = width / 2 val centerY = height / 2 val radius = width / 2 canvas.drawCircle(centerX.toFloat(), centerY.toFloat(), radius.toFloat(), paint) } 

    Возможно, вы можете оптимизировать этот код. Выполнение выделения в onDraw – не очень хорошая идея. Здесь вы можете найти объяснение.