Add UiUtils#updateLocationView and related stuff
This commit is contained in:
parent
37a7bf3083
commit
3162283ce0
6 changed files with 153 additions and 0 deletions
BIN
OsmAnd-telegram/res/drawable-hdpi/ic_direction_arrow.png
Normal file
BIN
OsmAnd-telegram/res/drawable-hdpi/ic_direction_arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd-telegram/res/drawable-mdpi/ic_direction_arrow.png
Normal file
BIN
OsmAnd-telegram/res/drawable-mdpi/ic_direction_arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd-telegram/res/drawable-xhdpi/ic_direction_arrow.png
Normal file
BIN
OsmAnd-telegram/res/drawable-xhdpi/ic_direction_arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
OsmAnd-telegram/res/drawable-xxhdpi/ic_direction_arrow.png
Normal file
BIN
OsmAnd-telegram/res/drawable-xxhdpi/ic_direction_arrow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1,63 @@
|
|||
package net.osmand.telegram.ui.views
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.ColorFilter
|
||||
import android.graphics.PixelFormat
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Drawable
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
|
||||
class DirectionDrawable(private val app: TelegramApplication) : Drawable() {
|
||||
|
||||
private var angle: Float = 0.toFloat()
|
||||
private var arrowImage: Drawable? = null
|
||||
|
||||
fun setImage(resourceId: Int, clrId: Int) {
|
||||
arrowImage = app.uiUtils.getIcon(resourceId, clrId)
|
||||
onBoundsChange(bounds)
|
||||
}
|
||||
|
||||
fun setAngle(angle: Float) {
|
||||
this.angle = angle
|
||||
}
|
||||
|
||||
override fun getIntrinsicWidth() = arrowImage?.intrinsicWidth ?: super.getIntrinsicWidth()
|
||||
|
||||
override fun getIntrinsicHeight() = arrowImage?.intrinsicHeight ?: super.getIntrinsicHeight()
|
||||
|
||||
override fun onBoundsChange(bounds: Rect) {
|
||||
super.onBoundsChange(bounds)
|
||||
if (arrowImage != null) {
|
||||
val w = arrowImage!!.intrinsicWidth
|
||||
val h = arrowImage!!.intrinsicHeight
|
||||
val dx = Math.max(0, bounds.width() - w)
|
||||
val dy = Math.max(0, bounds.height() - h)
|
||||
if (bounds.width() == 0 && bounds.height() == 0) {
|
||||
arrowImage!!.setBounds(0, 0, w, h)
|
||||
} else {
|
||||
arrowImage!!.setBounds(
|
||||
bounds.left + dx / 2,
|
||||
bounds.top + dy / 2,
|
||||
bounds.right - dx / 2,
|
||||
bounds.bottom - dy / 2
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun draw(canvas: Canvas) {
|
||||
canvas.save()
|
||||
if (arrowImage != null) {
|
||||
val r = bounds
|
||||
canvas.rotate(angle, r.centerX().toFloat(), r.centerY().toFloat())
|
||||
arrowImage!!.draw(canvas)
|
||||
}
|
||||
canvas.restore()
|
||||
}
|
||||
|
||||
override fun getOpacity() = PixelFormat.UNKNOWN
|
||||
|
||||
override fun setAlpha(alpha: Int) {}
|
||||
|
||||
override fun setColorFilter(cf: ColorFilter?) {}
|
||||
}
|
|
@ -1,15 +1,25 @@
|
|||
package net.osmand.telegram.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.LayerDrawable
|
||||
import android.hardware.Sensor
|
||||
import android.hardware.SensorManager
|
||||
import android.support.annotation.ColorInt
|
||||
import android.support.annotation.ColorRes
|
||||
import android.support.annotation.DrawableRes
|
||||
import android.support.v4.content.ContextCompat
|
||||
import android.support.v4.graphics.drawable.DrawableCompat
|
||||
import android.view.Surface
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import net.osmand.Location
|
||||
import net.osmand.data.LatLon
|
||||
import net.osmand.telegram.R
|
||||
import net.osmand.telegram.TelegramApplication
|
||||
import net.osmand.telegram.ui.views.DirectionDrawable
|
||||
import java.util.*
|
||||
|
||||
class UiUtils(private val app: TelegramApplication) {
|
||||
|
@ -122,4 +132,84 @@ class UiUtils(private val app: TelegramApplication) {
|
|||
|
||||
return bitmap
|
||||
}
|
||||
|
||||
fun updateLocationView(
|
||||
arrow: ImageView?,
|
||||
text: TextView?,
|
||||
lat: Double,
|
||||
lon: Double,
|
||||
cache: UpdateLocationViewCache
|
||||
) {
|
||||
updateLocationView(arrow, text, LatLon(lat, lon), cache)
|
||||
}
|
||||
|
||||
fun updateLocationView(
|
||||
arrow: ImageView?,
|
||||
text: TextView?,
|
||||
toLoc: LatLon,
|
||||
cache: UpdateLocationViewCache
|
||||
) {
|
||||
val fromLoc = app.locationProvider.lastKnownLocationLatLon
|
||||
val heading = app.locationProvider.heading
|
||||
val mes = FloatArray(2)
|
||||
val locPassive = fromLoc == null || cache.outdatedLocation
|
||||
val colorId = if (locPassive) R.color.icon_light else R.color.ctrl_active_light
|
||||
|
||||
fromLoc?.also { l ->
|
||||
Location.distanceBetween(toLoc.latitude, toLoc.longitude, l.latitude, l.longitude, mes)
|
||||
}
|
||||
|
||||
if (arrow != null) {
|
||||
var newImage = false
|
||||
val drawable = arrow.drawable
|
||||
val dd = if (drawable is DirectionDrawable) {
|
||||
drawable
|
||||
} else {
|
||||
newImage = true
|
||||
DirectionDrawable(app)
|
||||
}
|
||||
dd.setImage(R.drawable.ic_direction_arrow, colorId)
|
||||
if (fromLoc == null || heading == null) {
|
||||
dd.setAngle(0f)
|
||||
} else {
|
||||
dd.setAngle(mes[1] - heading + 180 + cache.screenOrientation)
|
||||
}
|
||||
if (newImage) {
|
||||
arrow.setImageDrawable(dd)
|
||||
}
|
||||
arrow.invalidate()
|
||||
}
|
||||
|
||||
if (text != null) {
|
||||
text.setTextColor(ContextCompat.getColor(app, colorId))
|
||||
val meters = if (fromLoc == null) 0f else mes[1]
|
||||
text.text = OsmandFormatter.getFormattedDistance(meters, app)
|
||||
}
|
||||
}
|
||||
|
||||
fun getUpdateLocationViewCache() =
|
||||
UpdateLocationViewCache().apply { screenOrientation = getScreenOrientation() }
|
||||
|
||||
private fun getScreenOrientation(): Int {
|
||||
// screenOrientation correction must not be applied for devices without compass
|
||||
val sensorManager = app.getSystemService(Context.SENSOR_SERVICE) as SensorManager?
|
||||
if (sensorManager?.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) == null) {
|
||||
return 0
|
||||
}
|
||||
|
||||
val windowManager = app.getSystemService(Context.WINDOW_SERVICE) as WindowManager?
|
||||
val rotation = windowManager?.defaultDisplay?.rotation ?: return 0
|
||||
|
||||
return when (rotation) {
|
||||
Surface.ROTATION_90 -> 90
|
||||
Surface.ROTATION_180 -> 180
|
||||
Surface.ROTATION_270 -> 270
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
|
||||
class UpdateLocationViewCache {
|
||||
var screenOrientation: Int = 0
|
||||
var outdatedLocation: Boolean = false
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue