Кастомный виджет в Android с масштабированием
Я пытаюсь сделать виджет который будет динамически подгружаемой картой. Но пока я поставил заглушку в виде картинки из настроек и пытаюсь написать масштабирование. Я перехожу в эту активность из другой, и у меня крашит после загрузки активности с этим виджетом.
class Map(context: Context) : View(context) {
private var dynamicMap: Array<Array<Tail>>? = null
private var lazyDynamicMap: Array<Array<Tail>>? = null
private var viewMap: Bitmap? = null
private var screenWidth: Int = 0
private var screenHeight: Int = 0
private var mapScaleFactor: Float = 1f
private var lastScaleFactor: Float = 1f
private var scaleGestureDetector: ScaleGestureDetector
init {
scaleGestureDetector = ScaleGestureDetector(context, object : ScaleGestureDetector.SimpleOnScaleGestureListener() {
override fun onScale(detector: ScaleGestureDetector): Boolean {
mapScaleFactor *= detector.scaleFactor / lastScaleFactor
lastScaleFactor = detector.scaleFactor
invalidate()
return true
}
override fun onScaleEnd(detector: ScaleGestureDetector) {
lastScaleFactor = 1f
}
})
// Получение инициализации viewMap из ресурсов
viewMap = BitmapFactory.decodeResource(resources, R.drawable.img_bg_setting)
// Получение ширины и высоты экрана
val displayMetrics = resources.displayMetrics
screenWidth = displayMetrics.widthPixels
screenHeight = displayMetrics.heightPixels
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
val desiredWidth = MeasureSpec.getSize(widthMeasureSpec)
val desiredHeight = MeasureSpec.getSize(heightMeasureSpec)
setMeasuredDimension(desiredWidth, desiredHeight)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
scaleGestureDetector.onTouchEvent(event)
return true
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
viewMap?.let {
val scaledWidth = it.width * mapScaleFactor
val scaledHeight = it.height * mapScaleFactor
val left = (width - scaledWidth) / 2
val top = (height - scaledHeight) / 2
canvas.drawBitmap(it, null, RectF(left, top, left + scaledWidth, top + scaledHeight), null)
}
}
}
XML-вёрстка:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".###">
<com.###.Map
android:id="@+id/###"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Заранее скажу, что среда не ругается на какие-либо красные ошибки.
Разве что пишет вот это в XML-вёрстке:
Missing classes
The following classes could not be found:
- com.###.Map (Fix Build Path, Edit XML, Create Class)
Tip: Try to build the project.
Tip: Try to refresh the layout.
Работаю через Android Studio. Gradle нормально проект собирает. Вместо ###
- ID приложения, там тоже всё указано правильно.
Карта будет собираться путём склеивания из тайлов из dynamicMap
, lazyDynamicMap
- будет хранить б`ольшую площадь, но после отрисовки основной.