#java #android #canvas #kotlin
#java #Android #холст #kotlin
Вопрос:
Я реализую пользовательскую кнопку для своего приложения 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)
}
Это Kotlin, но я думаю, с ним все ясно. Но в любом случае я могу предоставить 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()
«все в порядке», вид будет полностью заполнен. Это наводит меня на мысль, что что-то не так с моим Paint
классом или моим неправильным пониманием системы координат. Как правильно нарисовать круг с центром в центре зрения?
Комментарии:
1. Хм, я не знаком с Kotlin, но если я правильно следую коду, вы хотите удалить
x
изcenterX
вычисления иy
изcenterY
. То есть,var centerX = width / 2
,var centerY = height / 2
.2. Ну, это не работает.
3. О, точно. Вы не хотите выполнять эти вычисления там. Там у
View
него будет 0 измерений. Переместите эти вычисления в егоonSizeChanged()
метод. Или даже вonDraw()
, если вы просто хотите провести быстрый тест.
Ответ №1:
var centerX = x width / 2
var centerY = y height / 2
var radius = width / 2
Этот код будет вычислен при инициализации экземпляра. И в этот момент width
= 0 и height
= 0. Потому что представление еще не измерено.
Вы можете добавить Log.d(...)
точку останова или точку останова, 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
— не очень хорошая идея. Вы можете найти объяснение здесь.