Пользовательские представления являются важной частью разработки Android, поскольку они позволяют разработчикам создавать уникальные и персонализированные элементы пользовательского интерфейса, которые можно повторно использовать в своих приложениях. В этом ответе мы рассмотрим, как рисовать пользовательские представления в Android с помощью Kotlin, а также приведем несколько примеров и пояснений.
- Создание пользовательского класса представления Чтобы создать пользовательское представление в Android, нам сначала нужно создать новый класс, расширяющий класс View. Этот новый класс будет содержать весь пользовательский код рисования, который мы хотим реализовать. Вот пример:
class MyCustomView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) // Drawing code goes here } }
2. Реализация пользовательского рисования Когда у нас есть собственный класс представления, мы можем реализовать код пользовательского рисования в методе onDraw(). Этот метод вызывается всякий раз, когда необходимо перерисовать представление, например, при его первом создании, изменении его размера или при его аннулировании с помощью вызова invalidate().
Вот пример того, как нарисовать простой прямоугольник в пользовательском представлении:
override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) }
В этом примере мы используем объект canvas для рисования прямоугольника, покрывающего весь вид. Объект paint определяет цвет и стиль прямоугольника.
3. Настройка с помощью атрибутов Пользовательские представления также можно настроить с помощью атрибутов, которые позволяют разработчикам задавать такие свойства, как цвет, размер и стиль в файлах макета XML. Чтобы включить эту функцию, нам нужно объявить наши настраиваемые атрибуты в файле attrs.xml.
Вот пример того, как объявить пользовательский атрибут для пользовательского представления:
<declare-styleable name="MyCustomView"> <attr name="customColor" format="color" /> </declare-styleable>
В этом примере мы объявляем атрибут customColor, который можно использовать для установки цвета нашего пользовательского представления в XML.
Чтобы использовать этот атрибут в нашем пользовательском представлении, нам нужно получить его в конструкторе и применить к нашему объекту рисования:
class MyCustomView(context: Context?, attrs: AttributeSet?) : View(context, attrs) { private val paint = Paint() init { context?.theme?.obtainStyledAttributes(attrs, R.styleable.MyCustomView, 0, 0)?.apply { try { paint.color = getColor(R.styleable.MyCustomView_customColor, Color.BLACK) } finally { recycle() } } } override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) canvas?.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint) } }
В этом примере мы используем метод getStyledAttributes() для извлечения атрибута customColor из XML-файла макета. Затем мы используем этот цвет, чтобы установить цвет краски для нашего пользовательского представления.
4. Использование настраиваемых представлений в макетах
После того, как мы создали наш пользовательский класс представления и реализовали наш пользовательский код рисования, мы можем использовать наше пользовательское представление в файлах макета XML, как и любое другое представление.
Вот пример того, как использовать настраиваемое представление в файле макета XML:
<com.example.MyCustomView android:layout_width="match_parent" android:layout_height="wrap_content" app:customColor="#FF0000" />
Несколько примеров создания пользовательских представлений в Kotlin:
- Круглая полоса прогресса:
class CircularProgressView(context: Context, attrs: AttributeSet) : View(context, attrs) { private var progress = 0f private var progressColor = Color.BLUE private var bgColor = Color.GRAY private var strokeWidth = 10f private var rectF = RectF() init { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.CircularProgressView) progressColor = typedArray.getColor(R.styleable.CircularProgressView_progressColor, Color.BLUE) bgColor = typedArray.getColor(R.styleable.CircularProgressView_backgroundColor, Color.GRAY) strokeWidth = typedArray.getDimension(R.styleable.CircularProgressView_strokeWidth, 10f) typedArray.recycle() } override fun onDraw(canvas: Canvas) { super.onDraw(canvas) val centerX = width / 2f val centerY = height / 2f val radius = (width - strokeWidth) / 2f // draw background circle val bgPaint = Paint() bgPaint.color = bgColor bgPaint.isAntiAlias = true bgPaint.style = Paint.Style.STROKE bgPaint.strokeWidth = strokeWidth canvas.drawCircle(centerX, centerY, radius, bgPaint) // draw progress arc val progressPaint = Paint() progressPaint.color = progressColor progressPaint.isAntiAlias = true progressPaint.style = Paint.Style.STROKE progressPaint.strokeWidth = strokeWidth rectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius) canvas.drawArc(rectF, -90f, progress, false, progressPaint) } fun setProgress(progress: Float) { this.progress = progress invalidate() } fun setProgressColor(color: Int) { this.progressColor = color invalidate() } fun setBackgroundColor(color: Int) { this.bgColor = color invalidate() } fun setStrokeWidth(width: Float) { this.strokeWidth = width invalidate() } }
В этом примере класс CircularProgressView
расширяет класс View
и реализует пользовательское представление, которое рисует круговой индикатор выполнения. Представление имеет четыре настраиваемых атрибута progressColor
, backgroundColor
, strokeWidth
и progress
, которые можно задать в файле макета XML.
Метод onDraw
вызывается всякий раз, когда необходимо перерисовать представление. Он использует два объекта Paint
для рисования фонового круга и дуги прогресса на холсте.
Методы setProgress
, setProgressColor
, setBackgroundColor
и setStrokeWidth
используются для обновления свойств представления и аннулирования представления для запуска перерисовки.
Чтобы использовать это пользовательское представление в XML-файле макета, вы можете добавить следующий код:
<com.example.myapplication.CircularProgressView android:id="@+id/progressView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:progressColor="@color/progress_color" app:backgroundColor="@color/bg_color" app:strokeWidth="10dp" />
Затем в коде Kotlin вы можете получить доступ к индикатору выполнения и изменить его, используя метод findViewById
и вызывая методы пользовательского представления:
val progressView = findViewById<CircularProgressView>(R.id.progressView) progressView.setProgress(50f) progressView.setProgressColor(Color.RED)
2. Анимированный фон:
class AnimatedBackgroundView(context: Context, attrs: AttributeSet) : View(context, attrs) { private var radius: Float = 0f private var colors: IntArray = intArrayOf() private var handler = Handler(Looper.getMainLooper()) init { val typedArray = context.obtainStyledAttributes(attrs, R.styleable.AnimatedBackgroundView) radius = typedArray.getFloat(R.styleable.AnimatedBackgroundView_radius, 50f) colors = typedArray.getIntArray(R.styleable.AnimatedBackgroundView_colors) typedArray.recycle() } override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) if (colors.isNotEmpty()) { val paint = Paint() paint.isAntiAlias = true for (i in colors.indices) { paint.color = colors[i] val centerX = (i * radius * 2) + radius val centerY = height.toFloat() / 2 canvas?.drawCircle(centerX, centerY, radius, paint) } } invalidate() } fun startAnimating() { handler.postDelayed(object : Runnable { override fun run() { for (i in colors.indices) { colors[i] = getNextColor(colors[i]) } invalidate() handler.postDelayed(this, 1000) } }, 1000) } private fun getNextColor(color: Int): Int { val hsv = FloatArray(3) Color.colorToHSV(color, hsv) hsv[0] = (hsv[0] + 5) % 360 return Color.HSVToColor(hsv) } }
В этом примере класс AnimatedBackgroundView
расширяет класс View
и реализует пользовательское представление, которое рисует несколько кругов с изменяющимся цветом фона. Представление имеет два настраиваемых атрибута radius
и colors
, которые можно установить в файле макета XML.
Метод onDraw
вызывается всякий раз, когда необходимо перерисовать представление. Он использует объект Paint
для рисования на холсте кругов заданного радиуса и цвета.
Метод startAnimating
использует объект Handler
для публикации Runnable
, который обновляет цвета кругов каждую секунду и делает представление недействительным для запуска перерисовки.
Наконец, метод getNextColor
принимает входной цвет и возвращает следующий цвет в цветовом спектре, сдвигая значение оттенка на 5 градусов.
Каждое из этих пользовательских представлений можно реализовать в Kotlin с помощью классов Android Canvas и Paint, а также различных методов компоновки и обработки событий. Создавая настраиваемые представления, разработчики Android могут добавлять в свои приложения уникальные и привлекательные визуальные компоненты, улучшая взаимодействие с пользователем и функциональность.