Я реализую пользовательскую кнопку для моего приложения для 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
– не очень хорошая идея. Здесь вы можете найти объяснение.