mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added map in compose, removed MapFragment
This commit is contained in:
1 parent
acb851d4f6
commit
c592b8d3ce
23 files changed
+333
-737
No files matched your search
@@ -3,7 +3,6 @@ plugins {
|
||||
id "org.jetbrains.kotlin.android"
|
||||
id "org.jetbrains.kotlin.kapt"
|
||||
id "dagger.hilt.android.plugin"
|
||||
id "androidx.navigation.safeargs.kotlin"
|
||||
}
|
||||
|
||||
android {
|
||||
|
||||
@@ -26,12 +26,7 @@ import android.os.SystemClock
|
||||
import android.view.View
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.annotation.IdRes
|
||||
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.rtbishop.look4sat.presentation.bottomNav.MainScreenView
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
|
||||
@@ -54,24 +49,6 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Fragment.getNavResult(@IdRes id: Int, key: String, onResult: (result: T) -> Unit) {
|
||||
val backStackEntry = findNavController().getBackStackEntry(id)
|
||||
val observer = LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_RESUME && backStackEntry.savedStateHandle.contains(key)) {
|
||||
backStackEntry.savedStateHandle.get<T>(key)?.let(onResult)
|
||||
backStackEntry.savedStateHandle.remove<T>(key)
|
||||
}
|
||||
}
|
||||
backStackEntry.lifecycle.addObserver(observer)
|
||||
viewLifecycleOwner.lifecycle.addObserver(LifecycleEventObserver { _, event ->
|
||||
if (event == Lifecycle.Event.ON_DESTROY) backStackEntry.lifecycle.removeObserver(observer)
|
||||
})
|
||||
}
|
||||
|
||||
fun <T> Fragment.setNavResult(key: String, value: T) {
|
||||
findNavController().previousBackStackEntry?.savedStateHandle?.set(key, value)
|
||||
}
|
||||
|
||||
fun View.clickWithDebounce(debounceTime: Long = 875L, action: () -> Unit) {
|
||||
this.setOnClickListener(object : View.OnClickListener {
|
||||
private var lastClickTime: Long = 0
|
||||
|
||||
@@ -20,6 +20,7 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.rtbishop.look4sat.presentation.MainTheme
|
||||
import com.rtbishop.look4sat.presentation.aboutScreen.AboutScreen
|
||||
import com.rtbishop.look4sat.presentation.entriesScreen.EntriesScreen
|
||||
import com.rtbishop.look4sat.presentation.mapScreen.MapScreen
|
||||
import com.rtbishop.look4sat.presentation.passesScreen.PassesScreen
|
||||
import com.rtbishop.look4sat.presentation.passesScreen.PassesViewModel
|
||||
|
||||
@@ -58,7 +59,7 @@ fun NavigationGraph(navController: NavHostController) {
|
||||
EntriesScreen(navToPasses, passesViewModel = passesViewModel)
|
||||
}
|
||||
composable(BottomNavItem.Passes.screen_route) { PassesScreen(viewModel = passesViewModel) }
|
||||
composable(BottomNavItem.WorldMap.screen_route) {}
|
||||
composable(BottomNavItem.WorldMap.screen_route) { MapScreen() }
|
||||
composable(BottomNavItem.Settings.screen_route) {}
|
||||
composable(BottomNavItem.About.screen_route) { AboutScreen() }
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.DialogModesBinding
|
||||
import com.rtbishop.look4sat.domain.ISettingsManager
|
||||
import com.rtbishop.look4sat.presentation.setNavResult
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -74,7 +73,7 @@ class ModesDialog : AppCompatDialogFragment(), ModesAdapter.ModesClickListener {
|
||||
}
|
||||
modesBtnNeg.setOnClickListener { dismiss() }
|
||||
modesBtnPos.setOnClickListener {
|
||||
setNavResult("modes", selectedModes.toList())
|
||||
// setNavResult("modes", selectedModes.toList())
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
/*
|
||||
* Look4Sat. Amateur radio satellite tracker and pass predictor.
|
||||
* Copyright (C) 2019-2022 Arty Bishop (bishop.arty@gmail.com)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package com.rtbishop.look4sat.presentation.mapScreen
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.FragmentMapBinding
|
||||
import com.rtbishop.look4sat.domain.predict.GeoPos
|
||||
import com.rtbishop.look4sat.domain.predict.SatPos
|
||||
import com.rtbishop.look4sat.domain.predict.Satellite
|
||||
import com.rtbishop.look4sat.presentation.clickWithDebounce
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
|
||||
import org.osmdroid.util.GeoPoint
|
||||
import org.osmdroid.views.CustomZoomButtonsController
|
||||
import org.osmdroid.views.MapView
|
||||
import org.osmdroid.views.overlay.FolderOverlay
|
||||
import org.osmdroid.views.overlay.Marker
|
||||
import org.osmdroid.views.overlay.Polyline
|
||||
|
||||
@AndroidEntryPoint
|
||||
class MapFragment : Fragment(R.layout.fragment_map) {
|
||||
|
||||
private val viewModel: MapViewModel by viewModels()
|
||||
private val navArgs: MapFragmentArgs by navArgs()
|
||||
private val minLat = MapView.getTileSystem().minLatitude
|
||||
private val maxLat = MapView.getTileSystem().maxLatitude
|
||||
private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
strokeWidth = 3f
|
||||
style = Paint.Style.STROKE
|
||||
color = Color.RED
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
strokeJoin = Paint.Join.ROUND
|
||||
}
|
||||
private val footprintPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
strokeWidth = 3f
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
color = Color.parseColor("#FFE082")
|
||||
}
|
||||
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
textSize = 36f
|
||||
style = Paint.Style.FILL
|
||||
color = Color.parseColor("#CCFFFFFF")
|
||||
setShadowLayer(3f, 3f, 3f, Color.BLACK)
|
||||
}
|
||||
private val labelRect = Rect()
|
||||
private lateinit var binding: FragmentMapBinding
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentMapBinding.bind(view)
|
||||
setupComponents()
|
||||
setupObservers()
|
||||
}
|
||||
|
||||
private fun setupComponents() {
|
||||
val context = requireContext()
|
||||
val preferences = context.getSharedPreferences("default", Context.MODE_PRIVATE)
|
||||
Configuration.getInstance().load(context, preferences)
|
||||
binding.run {
|
||||
mapView.apply {
|
||||
setMultiTouchControls(true)
|
||||
setTileSource(TileSourceFactory.WIKIMEDIA)
|
||||
minZoomLevel = getMinZoom(resources.displayMetrics.heightPixels) + 0.25
|
||||
maxZoomLevel = 5.75
|
||||
controller.setZoom(minZoomLevel + 0.25)
|
||||
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
|
||||
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.setColorFilter(getColorFilter())
|
||||
setScrollableAreaLimitLatitude(maxLat, minLat, 0)
|
||||
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
|
||||
overlays.addAll(Array(4) { FolderOverlay() })
|
||||
}
|
||||
mapBtnBack.clickWithDebounce { findNavController().navigateUp() }
|
||||
mapBtnPrev.setOnClickListener { viewModel.scrollSelection(true) }
|
||||
mapBtnNext.setOnClickListener { viewModel.scrollSelection(false) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
viewModel.selectDefaultSatellite(navArgs.catNum)
|
||||
viewModel.stationPos.observe(viewLifecycleOwner) { handleStationPos(it) }
|
||||
viewModel.positions.observe(viewLifecycleOwner) { handlePositions(it) }
|
||||
viewModel.track.observe(viewLifecycleOwner) { handleTrack(it) }
|
||||
viewModel.footprint.observe(viewLifecycleOwner) { handleFootprint(it) }
|
||||
viewModel.mapData.observe(viewLifecycleOwner) { handleMapData(it) }
|
||||
}
|
||||
|
||||
private fun handleStationPos(stationPos: GeoPos) {
|
||||
binding.apply {
|
||||
Marker(mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_position)
|
||||
position = GeoPoint(stationPos.lat, stationPos.lon)
|
||||
mapView.overlays[0] = this
|
||||
mapView.invalidate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun handlePositions(posMap: Map<Satellite, GeoPos>) {
|
||||
binding.apply {
|
||||
val markers = FolderOverlay()
|
||||
posMap.entries.forEach {
|
||||
Marker(mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
|
||||
icon = getCustomTextIcon(it.key.data.name)
|
||||
try {
|
||||
position = GeoPoint(it.value.lat, it.value.lon)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
println(exception.stackTraceToString())
|
||||
}
|
||||
setOnMarkerClickListener { _, _ ->
|
||||
viewModel.selectSatellite(it.key)
|
||||
return@setOnMarkerClickListener true
|
||||
}
|
||||
markers.add(this)
|
||||
}
|
||||
}
|
||||
mapView.overlays[3] = markers
|
||||
mapView.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getCustomTextIcon(textLabel: String): Drawable {
|
||||
textPaint.getTextBounds(textLabel, 0, textLabel.length, labelRect)
|
||||
val iconSize = 8f
|
||||
val width = labelRect.width() + iconSize * 2f
|
||||
val height = textPaint.textSize * 3f + iconSize * 2f
|
||||
val bitmap = Bitmap.createBitmap(width.toInt(), height.toInt(), Bitmap.Config.ARGB_8888)
|
||||
Canvas(bitmap).run {
|
||||
drawCircle(width / 2f, height / 2f, iconSize, textPaint)
|
||||
drawText(textLabel, iconSize / 2f, height - iconSize, textPaint)
|
||||
}
|
||||
return BitmapDrawable(binding.mapView.context.resources, bitmap)
|
||||
}
|
||||
|
||||
private fun handleTrack(satTrack: List<List<GeoPos>>) {
|
||||
val center = GeoPoint(satTrack[0][0].lat, satTrack[0][0].lon)
|
||||
val trackOverlay = FolderOverlay()
|
||||
satTrack.forEach { track ->
|
||||
val trackPoints = track.map { GeoPoint(it.lat, it.lon) }
|
||||
Polyline().apply {
|
||||
try {
|
||||
setPoints(trackPoints)
|
||||
outlinePaint.set(trackPaint)
|
||||
trackOverlay.add(this)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
println(exception.stackTraceToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
binding.mapView.overlays[1] = trackOverlay
|
||||
binding.mapView.controller.animateTo(center)
|
||||
}
|
||||
|
||||
private fun handleFootprint(satPos: SatPos) {
|
||||
val footprintPoints = satPos.getRangeCircle().map { GeoPoint(it.lat, it.lon) }
|
||||
val footprintOverlay = Polyline().apply {
|
||||
outlinePaint.set(footprintPaint)
|
||||
try {
|
||||
setPoints(footprintPoints)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
println(exception.stackTraceToString())
|
||||
}
|
||||
}
|
||||
binding.mapView.overlays[2] = footprintOverlay
|
||||
}
|
||||
|
||||
private fun handleMapData(mapData: MapData) {
|
||||
binding.apply {
|
||||
mapTimer.text = mapData.aosTime
|
||||
mapDataPeriod.text = String.format(getString(R.string.map_period, mapData.period))
|
||||
mapDataPhase.text = String.format(getString(R.string.map_phase), mapData.phase)
|
||||
mapAzimuth.text = String.format(getString(R.string.map_azimuth), mapData.azimuth)
|
||||
mapElevation.text = String.format(getString(R.string.map_elevation), mapData.elevation)
|
||||
mapDataAlt.text = String.format(getString(R.string.map_altitude), mapData.altitude)
|
||||
mapDataDst.text = String.format(getString(R.string.map_distance), mapData.range)
|
||||
mapDataLat.text =
|
||||
String.format(getString(R.string.map_latitude), mapData.osmPos.lat)
|
||||
mapDataLon.text =
|
||||
String.format(getString(R.string.map_longitude), mapData.osmPos.lon)
|
||||
mapDataQth.text = String.format(getString(R.string.map_qth), mapData.qthLoc)
|
||||
mapDataVel.text = String.format(getString(R.string.map_velocity), mapData.velocity)
|
||||
if (mapData.eclipsed) {
|
||||
mapDataVisibility.text = getString(R.string.map_eclipsed)
|
||||
} else {
|
||||
mapDataVisibility.text = getString(R.string.map_visible)
|
||||
}
|
||||
}
|
||||
binding.mapView.invalidate()
|
||||
}
|
||||
|
||||
private fun getColorFilter(): ColorMatrixColorFilter {
|
||||
val grayScaleMatrix = ColorMatrix().apply { setSaturation(0f) }
|
||||
val negativeMatrix = ColorMatrix(
|
||||
floatArrayOf(
|
||||
-1f, 0f, 0f, 0f, 255f,
|
||||
0f, -1f, 0f, 0f, 255f,
|
||||
0f, 0f, -1f, 0f, 255f,
|
||||
0f, 0f, 0f, 1f, 0f
|
||||
)
|
||||
)
|
||||
negativeMatrix.preConcat(grayScaleMatrix)
|
||||
return ColorMatrixColorFilter(negativeMatrix)
|
||||
}
|
||||
|
||||
private fun getMinZoom(screenHeight: Int): Double {
|
||||
return MapView.getTileSystem().getLatitudeZoom(maxLat, minLat, screenHeight)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,247 @@
|
||||
package com.rtbishop.look4sat.presentation.mapScreen
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.*
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ElevatedCard
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.hilt.navigation.compose.hiltViewModel
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.domain.predict.GeoPos
|
||||
import com.rtbishop.look4sat.domain.predict.SatPos
|
||||
import com.rtbishop.look4sat.domain.predict.Satellite
|
||||
import org.osmdroid.config.Configuration
|
||||
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
|
||||
import org.osmdroid.util.GeoPoint
|
||||
import org.osmdroid.views.CustomZoomButtonsController
|
||||
import org.osmdroid.views.MapView
|
||||
import org.osmdroid.views.overlay.FolderOverlay
|
||||
import org.osmdroid.views.overlay.Marker
|
||||
import org.osmdroid.views.overlay.Polyline
|
||||
import timber.log.Timber
|
||||
|
||||
private val minLat = MapView.getTileSystem().minLatitude
|
||||
private val maxLat = MapView.getTileSystem().maxLatitude
|
||||
private val trackPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
strokeWidth = 3f
|
||||
style = Paint.Style.STROKE
|
||||
color = Color.RED
|
||||
strokeCap = Paint.Cap.ROUND
|
||||
strokeJoin = Paint.Join.ROUND
|
||||
}
|
||||
private val footprintPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
strokeWidth = 3f
|
||||
style = Paint.Style.FILL_AND_STROKE
|
||||
color = Color.parseColor("#FFE082")
|
||||
}
|
||||
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
textSize = 36f
|
||||
style = Paint.Style.FILL
|
||||
color = Color.parseColor("#CCFFFFFF")
|
||||
setShadowLayer(3f, 3f, 3f, Color.BLACK)
|
||||
}
|
||||
private val labelRect = Rect()
|
||||
|
||||
@Composable
|
||||
fun MapScreen(viewModel: MapViewModel = hiltViewModel()) {
|
||||
val context = LocalContext.current
|
||||
Configuration.getInstance().load(context, viewModel.getPreferences())
|
||||
viewModel.selectDefaultSatellite(-1)
|
||||
val stationPos = viewModel.stationPos.observeAsState()
|
||||
val positions = viewModel.positions.observeAsState()
|
||||
val satTrack = viewModel.track.observeAsState()
|
||||
val footprint = viewModel.footprint.observeAsState()
|
||||
val positionClick = { satellite: Satellite -> viewModel.selectSatellite(satellite) }
|
||||
Timber.d("MapScreen recomposition")
|
||||
Column(modifier = Modifier.padding(6.dp), verticalArrangement = Arrangement.spacedBy(6.dp)) {
|
||||
ElevatedCard(modifier = Modifier.fillMaxSize()) {
|
||||
MapView(modifier = Modifier.fillMaxSize()) { mapView ->
|
||||
Timber.d("MapView recomposition")
|
||||
stationPos.value?.let { setStationPosition(it, mapView) }
|
||||
positions.value?.let { setPositions(it, mapView, positionClick) }
|
||||
satTrack.value?.let { setSatelliteTrack(it, mapView) }
|
||||
footprint.value?.let { setFootprint(it, mapView) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setStationPosition(stationPos: GeoPos, mapView: MapView) {
|
||||
Marker(mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
|
||||
icon = ContextCompat.getDrawable(mapView.context, R.drawable.ic_position)
|
||||
position = GeoPoint(stationPos.lat, stationPos.lon)
|
||||
mapView.overlays[0] = this
|
||||
mapView.invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
private fun setPositions(
|
||||
posMap: Map<Satellite, GeoPos>, mapView: MapView, action: (Satellite) -> Unit
|
||||
) {
|
||||
val markers = FolderOverlay()
|
||||
posMap.entries.forEach {
|
||||
Marker(mapView).apply {
|
||||
setInfoWindow(null)
|
||||
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
|
||||
icon = getCustomTextIcon(it.key.data.name, mapView)
|
||||
try {
|
||||
position = GeoPoint(it.value.lat, it.value.lon)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
println(exception.stackTraceToString())
|
||||
}
|
||||
setOnMarkerClickListener { _, _ ->
|
||||
action(it.key)
|
||||
return@setOnMarkerClickListener true
|
||||
}
|
||||
markers.add(this)
|
||||
}
|
||||
}
|
||||
mapView.overlays[3] = markers
|
||||
mapView.invalidate()
|
||||
}
|
||||
|
||||
private fun getCustomTextIcon(textLabel: String, mapView: MapView): Drawable {
|
||||
textPaint.getTextBounds(textLabel, 0, textLabel.length, labelRect)
|
||||
val iconSize = 8f
|
||||
val width = labelRect.width() + iconSize * 2f
|
||||
val height = textPaint.textSize * 3f + iconSize * 2f
|
||||
val bitmap = Bitmap.createBitmap(width.toInt(), height.toInt(), Bitmap.Config.ARGB_8888)
|
||||
Canvas(bitmap).run {
|
||||
drawCircle(width / 2f, height / 2f, iconSize, textPaint)
|
||||
drawText(textLabel, iconSize / 2f, height - iconSize, textPaint)
|
||||
}
|
||||
return BitmapDrawable(mapView.context.resources, bitmap)
|
||||
}
|
||||
|
||||
private fun setSatelliteTrack(satTrack: List<List<GeoPos>>, mapView: MapView) {
|
||||
// val center = GeoPoint(satTrack[0][0].lat, satTrack[0][0].lon)
|
||||
val trackOverlay = FolderOverlay()
|
||||
satTrack.forEach { track ->
|
||||
val trackPoints = track.map { GeoPoint(it.lat, it.lon) }
|
||||
Polyline().apply {
|
||||
try {
|
||||
setPoints(trackPoints)
|
||||
outlinePaint.set(trackPaint)
|
||||
trackOverlay.add(this)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
println(exception.stackTraceToString())
|
||||
}
|
||||
}
|
||||
}
|
||||
mapView.overlays[1] = trackOverlay
|
||||
// mapView.controller.animateTo(center)
|
||||
}
|
||||
|
||||
private fun setFootprint(satPos: SatPos, mapView: MapView) {
|
||||
val footprintPoints = satPos.getRangeCircle().map { GeoPoint(it.lat, it.lon) }
|
||||
val footprintOverlay = Polyline().apply {
|
||||
outlinePaint.set(footprintPaint)
|
||||
try {
|
||||
setPoints(footprintPoints)
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
println(exception.stackTraceToString())
|
||||
}
|
||||
}
|
||||
mapView.overlays[2] = footprintOverlay
|
||||
}
|
||||
|
||||
//private fun handleMapData(mapData: MapData) {
|
||||
// binding.apply {
|
||||
// mapTimer.text = mapData.aosTime
|
||||
// mapDataPeriod.text = String.format(getString(R.string.map_period, mapData.period))
|
||||
// mapDataPhase.text = String.format(getString(R.string.map_phase), mapData.phase)
|
||||
// mapAzimuth.text = String.format(getString(R.string.map_azimuth), mapData.azimuth)
|
||||
// mapElevation.text = String.format(getString(R.string.map_elevation), mapData.elevation)
|
||||
// mapDataAlt.text = String.format(getString(R.string.map_altitude), mapData.altitude)
|
||||
// mapDataDst.text = String.format(getString(R.string.map_distance), mapData.range)
|
||||
// mapDataLat.text =
|
||||
// String.format(getString(R.string.map_latitude), mapData.osmPos.lat)
|
||||
// mapDataLon.text =
|
||||
// String.format(getString(R.string.map_longitude), mapData.osmPos.lon)
|
||||
// mapDataQth.text = String.format(getString(R.string.map_qth), mapData.qthLoc)
|
||||
// mapDataVel.text = String.format(getString(R.string.map_velocity), mapData.velocity)
|
||||
// if (mapData.eclipsed) {
|
||||
// mapDataVisibility.text = getString(R.string.map_eclipsed)
|
||||
// } else {
|
||||
// mapDataVisibility.text = getString(R.string.map_visible)
|
||||
// }
|
||||
// }
|
||||
// binding.mapView.invalidate()
|
||||
//}
|
||||
|
||||
@Composable
|
||||
private fun MapView(modifier: Modifier = Modifier, update: ((map: MapView) -> Unit)? = null) {
|
||||
val mapView = rememberMapViewWithLifecycle()
|
||||
AndroidView({ mapView }, modifier) { update?.invoke(it) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberMapViewWithLifecycle(context: Context = LocalContext.current): MapView {
|
||||
// add clipToOutline = true if needed
|
||||
val mapView = remember { MapView(context).apply { id = R.id.osm_map_view } }.apply {
|
||||
setMultiTouchControls(true)
|
||||
setTileSource(TileSourceFactory.WIKIMEDIA)
|
||||
minZoomLevel = getMinZoom(resources.displayMetrics.heightPixels) + 0.25
|
||||
maxZoomLevel = 5.75
|
||||
controller.setZoom(minZoomLevel + 0.25)
|
||||
zoomController.setVisibility(CustomZoomButtonsController.Visibility.NEVER)
|
||||
overlayManager.tilesOverlay.loadingBackgroundColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.loadingLineColor = Color.TRANSPARENT
|
||||
overlayManager.tilesOverlay.setColorFilter(getColorFilter())
|
||||
setScrollableAreaLimitLatitude(maxLat, minLat, 0)
|
||||
// add overlays: 0 - GSP, 1 - SatTrack, 2 - SatFootprint, 3 - SatIcons
|
||||
overlays.addAll(Array(4) { FolderOverlay() })
|
||||
}
|
||||
// Makes MapView follow the lifecycle of this composable
|
||||
val lifecycleObserver = rememberMapViewLifecycleObserver(mapView)
|
||||
val lifecycle = LocalLifecycleOwner.current.lifecycle
|
||||
DisposableEffect(lifecycle) {
|
||||
lifecycle.addObserver(lifecycleObserver)
|
||||
onDispose { lifecycle.removeObserver(lifecycleObserver) }
|
||||
}
|
||||
return mapView
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun rememberMapViewLifecycleObserver(mapView: MapView) = remember(mapView) {
|
||||
LifecycleEventObserver { _, event ->
|
||||
when (event) {
|
||||
Lifecycle.Event.ON_RESUME -> mapView.onResume()
|
||||
Lifecycle.Event.ON_PAUSE -> mapView.onPause()
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getColorFilter(): ColorMatrixColorFilter {
|
||||
val grayScaleMatrix = ColorMatrix().apply { setSaturation(0f) }
|
||||
val negativeMatrix = ColorMatrix(
|
||||
floatArrayOf(
|
||||
-1f, 0f, 0f, 0f, 255f, 0f, -1f, 0f, 0f, 255f, 0f, 0f, -1f, 0f, 255f, 0f, 0f, 0f, 1f, 0f
|
||||
)
|
||||
)
|
||||
negativeMatrix.preConcat(grayScaleMatrix)
|
||||
return ColorMatrixColorFilter(negativeMatrix)
|
||||
}
|
||||
|
||||
private fun getMinZoom(screenHeight: Int): Double {
|
||||
return MapView.getTileSystem().getLatitudeZoom(maxLat, minLat, screenHeight)
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.presentation.mapScreen
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import androidx.lifecycle.*
|
||||
import com.rtbishop.look4sat.domain.IDataRepository
|
||||
import com.rtbishop.look4sat.domain.ISatelliteManager
|
||||
@@ -36,9 +37,10 @@ import kotlin.math.min
|
||||
|
||||
@HiltViewModel
|
||||
class MapViewModel @Inject constructor(
|
||||
private val satelliteManager: ISatelliteManager,
|
||||
private val preferences: SharedPreferences,
|
||||
private val repository: IDataRepository,
|
||||
private val settings: ISettingsManager,
|
||||
private val satelliteManager: ISatelliteManager,
|
||||
private val settings: ISettingsManager
|
||||
) : ViewModel() {
|
||||
|
||||
private val stationPosition = settings.loadStationPosition()
|
||||
@@ -66,6 +68,8 @@ class MapViewModel @Inject constructor(
|
||||
private val _positions = MutableLiveData<Map<Satellite, GeoPos>>()
|
||||
val positions: LiveData<Map<Satellite, GeoPos>> = _positions
|
||||
|
||||
fun getPreferences() = preferences
|
||||
|
||||
fun scrollSelection(decrement: Boolean) {
|
||||
if (allSatellites.isNotEmpty()) {
|
||||
val index = allSatellites.indexOf(selectedSatellite)
|
||||
@@ -184,8 +188,19 @@ class MapViewModel @Inject constructor(
|
||||
val phase = satPos.phase.toDegrees()
|
||||
val visibility = satPos.eclipsed
|
||||
val satData = MapData(
|
||||
sat.data.catnum, sat.data.name, aosTime, azimuth, elevation, satPos.distance,
|
||||
satPos.altitude, velocity, qthLoc, osmPos, sat.data.orbitalPeriod, phase, visibility
|
||||
sat.data.catnum,
|
||||
sat.data.name,
|
||||
aosTime,
|
||||
azimuth,
|
||||
elevation,
|
||||
satPos.distance,
|
||||
satPos.altitude,
|
||||
velocity,
|
||||
qthLoc,
|
||||
osmPos,
|
||||
sat.data.orbitalPeriod,
|
||||
phase,
|
||||
visibility
|
||||
)
|
||||
_mapData.postValue(satData)
|
||||
}
|
||||
|
||||
@@ -17,14 +17,10 @@
|
||||
*/
|
||||
package com.rtbishop.look4sat.presentation.radarScreen
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.provider.CalendarContract
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator
|
||||
@@ -32,7 +28,6 @@ import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.FragmentRadarBinding
|
||||
import com.rtbishop.look4sat.domain.predict.SatPass
|
||||
import com.rtbishop.look4sat.domain.predict.SatPos
|
||||
import com.rtbishop.look4sat.presentation.clickWithDebounce
|
||||
import com.rtbishop.look4sat.utility.toDegrees
|
||||
import com.rtbishop.look4sat.utility.toTimerString
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -41,7 +36,6 @@ import dagger.hilt.android.AndroidEntryPoint
|
||||
class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
|
||||
private val viewModel: RadarViewModel by viewModels()
|
||||
private val navArgs: RadarFragmentArgs by navArgs()
|
||||
private val radioAdapter = RadioAdapter()
|
||||
private var binding: FragmentRadarBinding? = null
|
||||
private var radarView: RadarView? = null
|
||||
@@ -78,7 +72,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
}
|
||||
|
||||
private fun setupObservers() {
|
||||
viewModel.getPass(navArgs.catNum, navArgs.aosTime).observe(viewLifecycleOwner) { pass ->
|
||||
viewModel.getPass(45000, System.currentTimeMillis()).observe(viewLifecycleOwner) { pass ->
|
||||
binding?.run {
|
||||
radarView = RadarView(requireContext()).apply {
|
||||
setShowAim(viewModel.getUseCompass())
|
||||
@@ -103,24 +97,16 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
viewModel.orientation.observe(viewLifecycleOwner) { value ->
|
||||
radarView?.setOrientation(value.first, value.second, value.third)
|
||||
}
|
||||
radarBtnBack.clickWithDebounce { findNavController().navigateUp() }
|
||||
radarBtnMap.clickWithDebounce {
|
||||
val direction = RadarFragmentDirections.globalToMap(pass.catNum)
|
||||
findNavController().navigate(direction)
|
||||
}
|
||||
radarBtnNotify.clickWithDebounce {
|
||||
val intent = Intent(Intent.ACTION_INSERT)
|
||||
.setData(CalendarContract.Events.CONTENT_URI)
|
||||
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, pass.aosTime)
|
||||
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, pass.losTime)
|
||||
.putExtra(CalendarContract.Events.TITLE, pass.name)
|
||||
.putExtra(CalendarContract.Events.DESCRIPTION, "Look4Sat")
|
||||
startActivity(intent)
|
||||
}
|
||||
radarBtnSettings.clickWithDebounce {
|
||||
val direction = RadarFragmentDirections.globalToSettings()
|
||||
findNavController().navigate(direction)
|
||||
}
|
||||
// radarBtnBack.clickWithDebounce { findNavController().navigateUp() }
|
||||
// radarBtnMap.clickWithDebounce {
|
||||
// val direction = RadarFragmentDirections.globalToMap(pass.catNum)
|
||||
// findNavController().navigate(direction)
|
||||
// }
|
||||
// radarBtnNotify.isEnabled = false
|
||||
// radarBtnSettings.clickWithDebounce {
|
||||
// val direction = RadarFragmentDirections.globalToSettings()
|
||||
// findNavController().navigate(direction)
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -150,7 +136,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
|
||||
radarTimer.text = millisBeforeEnd.toTimerString()
|
||||
if (timeNow > satPass.losTime) {
|
||||
radarTimer.text = 0L.toTimerString()
|
||||
findNavController().navigateUp()
|
||||
// findNavController().navigateUp()
|
||||
}
|
||||
}
|
||||
} else radarTimer.text = 0L.toTimerString()
|
||||
|
||||
+1
-2
@@ -26,7 +26,6 @@ import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.DialogLocatorBinding
|
||||
import com.rtbishop.look4sat.domain.ISettingsManager
|
||||
import com.rtbishop.look4sat.presentation.setNavResult
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -50,7 +49,7 @@ class LocatorDialog : AppCompatDialogFragment() {
|
||||
)
|
||||
locatorEdit.setText(preferences.loadStationLocator())
|
||||
locatorBtnPos.setOnClickListener {
|
||||
setNavResult("locator", locatorEdit.text.toString())
|
||||
// setNavResult("locator", locatorEdit.text.toString())
|
||||
dismiss()
|
||||
}
|
||||
locatorBtnNeg.setOnClickListener { dismiss() }
|
||||
|
||||
+11
-12
@@ -26,7 +26,6 @@ import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.DialogPositionBinding
|
||||
import com.rtbishop.look4sat.domain.ISettingsManager
|
||||
import com.rtbishop.look4sat.presentation.setNavResult
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -52,17 +51,17 @@ class PositionDialog : AppCompatDialogFragment() {
|
||||
positionLatEdit.setText(location.lat.toString())
|
||||
positionLonEdit.setText(location.lon.toString())
|
||||
positionBtnPos.setOnClickListener {
|
||||
val latitude = try {
|
||||
positionLatEdit.text.toString().toDouble()
|
||||
} catch (exception: Exception) {
|
||||
180.0
|
||||
}
|
||||
val longitude = try {
|
||||
positionLonEdit.text.toString().toDouble()
|
||||
} catch (exception: Exception) {
|
||||
400.0
|
||||
}
|
||||
setNavResult("position", Pair(latitude, longitude))
|
||||
// val latitude = try {
|
||||
// positionLatEdit.text.toString().toDouble()
|
||||
// } catch (exception: Exception) {
|
||||
// 180.0
|
||||
// }
|
||||
// val longitude = try {
|
||||
// positionLonEdit.text.toString().toDouble()
|
||||
// } catch (exception: Exception) {
|
||||
// 400.0
|
||||
// }
|
||||
// setNavResult("position", Pair(latitude, longitude))
|
||||
dismiss()
|
||||
}
|
||||
positionBtnNeg.setOnClickListener { dismiss() }
|
||||
|
||||
+18
-20
@@ -31,14 +31,12 @@ import androidx.core.widget.doOnTextChanged
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.rtbishop.look4sat.BuildConfig
|
||||
import com.rtbishop.look4sat.R
|
||||
import com.rtbishop.look4sat.databinding.FragmentSettingsBinding
|
||||
import com.rtbishop.look4sat.domain.model.DataState
|
||||
import com.rtbishop.look4sat.domain.predict.GeoPos
|
||||
import com.rtbishop.look4sat.presentation.clickWithDebounce
|
||||
import com.rtbishop.look4sat.presentation.getNavResult
|
||||
import com.rtbishop.look4sat.utility.isValidIPv4
|
||||
import com.rtbishop.look4sat.utility.isValidPort
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@@ -79,7 +77,7 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding = FragmentSettingsBinding.bind(view).apply {
|
||||
settingsBtnBack.clickWithDebounce { findNavController().navigateUp() }
|
||||
// settingsBtnBack.clickWithDebounce { findNavController().navigateUp() }
|
||||
settingsScroll.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, y, _, newY ->
|
||||
if (y > newY) settingsFab.hide() else settingsFab.show()
|
||||
})
|
||||
@@ -115,20 +113,20 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
settingsLocation.locationBtnGps.clickWithDebounce {
|
||||
locationRequest.launch(arrayOf(locationFine, locationCoarse))
|
||||
}
|
||||
settingsLocation.locationBtnManual.clickWithDebounce {
|
||||
val action = SettingsFragmentDirections.globalToPosition()
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
settingsLocation.locationBtnQth.clickWithDebounce {
|
||||
val action = SettingsFragmentDirections.globalToLocator()
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
getNavResult<Pair<Double, Double>>(R.id.nav_settings, "position") { position ->
|
||||
viewModel.setStationPosition(position.first, position.second)
|
||||
}
|
||||
getNavResult<String>(R.id.nav_settings, "locator") { locator ->
|
||||
viewModel.setPositionFromQth(locator)
|
||||
}
|
||||
// settingsLocation.locationBtnManual.clickWithDebounce {
|
||||
// val action = SettingsFragmentDirections.globalToPosition()
|
||||
// findNavController().navigate(action)
|
||||
// }
|
||||
// settingsLocation.locationBtnQth.clickWithDebounce {
|
||||
// val action = SettingsFragmentDirections.globalToLocator()
|
||||
// findNavController().navigate(action)
|
||||
// }
|
||||
// getNavResult<Pair<Double, Double>>(R.id.nav_settings, "position") { position ->
|
||||
// viewModel.setStationPosition(position.first, position.second)
|
||||
// }
|
||||
// getNavResult<String>(R.id.nav_settings, "locator") { locator ->
|
||||
// viewModel.setPositionFromQth(locator)
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,9 +144,9 @@ class SettingsFragment : Fragment(R.layout.fragment_settings) {
|
||||
val radiosFormat = getString(R.string.data_radios)
|
||||
settingsData.dataRadios.text = String.format(radiosFormat, number)
|
||||
}
|
||||
getNavResult<List<String>>(R.id.nav_settings, "sources") {
|
||||
viewModel.updateFromWeb()
|
||||
}
|
||||
// getNavResult<List<String>>(R.id.nav_settings, "sources") {
|
||||
// viewModel.updateFromWeb()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:autoMirrored="true"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:autoMirrored="true"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
<vector android:height="24dp" android:viewportHeight="512"
|
||||
android:viewportWidth="512" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#000000" android:pathData="M495.3,425.74H255.18c-3.58,-52 -23.78,-100.69 -58.12,-140.07L401.37,81.37c6.52,-6.52 6.52,-17.09 0,-23.61c-6.52,-6.52 -17.09,-6.52 -23.61,0L162.23,273.29L4.89,430.63c-4.77,4.77 -6.21,11.96 -3.62,18.2s8.67,10.3 15.42,10.3h222.61h256c9.22,0 16.7,-7.47 16.7,-16.7C512,433.21 504.52,425.74 495.3,425.74z"/>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="512"
|
||||
android:viewportHeight="512">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M495.3,425.74H255.18c-3.58,-52 -23.78,-100.69 -58.12,-140.07L401.37,81.37c6.52,-6.52 6.52,-17.09 0,-23.61c-6.52,-6.52 -17.09,-6.52 -23.61,0L162.23,273.29L4.89,430.63c-4.77,4.77 -6.21,11.96 -3.62,18.2s8.67,10.3 15.42,10.3h222.61h256c9.22,0 16.7,-7.47 16.7,-16.7C512,433.21 504.52,425.74 495.3,425.74z" />
|
||||
</vector>
|
||||
@@ -1,7 +1,8 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:autoMirrored="true"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M4.25,5.61C6.27,8.2 10,13 10,13v6c0,0.55 0.45,1 1,1h2c0.55,0 1,-0.45 1,-1v-6c0,0 3.72,-4.8 5.74,-7.39C20.25,4.95 19.78,4 18.95,4H5.04C4.21,4 3.74,4.95 4.25,5.61z" />
|
||||
</vector>
|
||||
@@ -1,13 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="512"
|
||||
android:viewportHeight="512">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M437.02,74.98C388.67,26.63 324.38,0 256,0S123.33,26.63 74.98,74.98C26.63,123.33 0,187.62 0,256S26.63,388.67 74.98,437.02C123.33,485.37 187.62,512 256,512c68.38,0 132.67,-26.63 181.02,-74.98C485.37,388.67 512,324.38 512,256S485.37,123.33 437.02,74.98zM415.51,415.51c-42.61,42.61 -99.26,66.07 -159.51,66.07c-60.26,0 -116.9,-23.47 -159.51,-66.07C53.88,372.9 30.42,316.26 30.42,256S53.88,139.1 96.49,96.49C139.1,53.88 195.74,30.42 256,30.42c55.16,0 107.29,19.67 148.39,55.68l-41.21,41.21C333.14,102.2 295.63,88.52 256,88.52c-92.35,0 -167.48,75.13 -167.48,167.48S163.65,423.48 256,423.48s167.48,-75.13 167.48,-167.48h-30.42c0,75.57 -61.49,137.06 -137.06,137.06S118.94,331.58 118.94,256S180.43,118.94 256,118.94c31.49,0 61.35,10.56 85.57,29.98l-41.53,41.53c-12.91,-8.72 -28.12,-13.4 -44.04,-13.4c-43.53,0 -78.95,35.42 -78.95,78.95c0,43.53 35.42,78.95 78.95,78.95s78.95,-35.42 78.95,-78.95h-30.42c0,26.76 -21.77,48.54 -48.54,48.54S207.46,282.76 207.46,256c0,-26.76 21.77,-48.54 48.54,-48.54c7.72,0 15.15,1.8 21.84,5.18l-32.6,32.6l21.51,21.51l159.15,-159.15c36.01,41.11 55.68,93.24 55.68,148.39C481.58,316.26 458.12,372.9 415.51,415.51z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M396.71,197.71m-18.42,0a18.42,18.42 0,1 1,36.85 0a18.42,18.42 0,1 1,-36.85 0" />
|
||||
</vector>
|
||||
@@ -1,6 +1,7 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:autoMirrored="true"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="287.97"
|
||||
android:viewportHeight="287.97">
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="503.61"
|
||||
android:viewportHeight="503.61">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M251.8,0C113.31,0 0,112.47 0,251.8s113.31,251.8 251.8,251.8s251.8,-113.31 251.8,-251.8S390.3,0 251.8,0zM251.8,486.82c-129.26,0 -235.02,-105.76 -235.02,-235.02S122.54,16.79 251.8,16.79S486.82,122.54 486.82,251.8S381.06,486.82 251.8,486.82z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M251.8,83.93c-92.33,0 -167.87,75.54 -167.87,167.87c0,9.23 0.84,18.47 2.52,26.86c0,4.2 5.04,7.55 9.23,6.72c4.2,0 7.55,-5.04 6.72,-9.23c-0.84,-7.55 -1.68,-15.95 -1.68,-24.34c0,-83.1 67.99,-151.08 151.08,-151.08s151.08,67.99 151.08,151.08s-67.99,151.08 -151.08,151.08c-37.55,0 -72.9,-13.13 -100.64,-38.69l47.21,-47.21c15.02,12.31 33.58,18.75 53.43,18.75c46.16,0 83.93,-37.77 83.93,-83.93s-37.77,-83.93 -83.93,-83.93s-83.93,37.77 -83.93,83.93c0,5.04 0,9.23 1.68,13.43c0,4.2 5.04,7.55 9.23,6.72c4.2,0 7.55,-5.04 6.72,-9.23c-0.84,-3.36 -0.84,-7.55 -0.84,-10.91c0,-36.93 30.22,-67.15 67.15,-67.15s67.15,30.22 67.15,67.15c0,36.93 -30.22,67.15 -67.15,67.15c-15.56,0 -29.91,-4.78 -41.58,-13.81l24.48,-24.48c5.02,2.99 10.87,4.72 17.1,4.72c18.47,0 33.57,-15.11 33.57,-33.57s-15.11,-33.57 -33.57,-33.57s-33.57,15.11 -33.57,33.57c0,6.24 1.73,12.09 4.72,17.1l-30.74,30.74c0,0 0,0 0,0s0,0 0,0l-58.75,58.75c0,0 0,0 0,0s0,0 0,0l-30.22,30.22c-3.36,3.36 -3.36,8.39 0,11.75c1.68,1.68 3.36,2.52 5.88,2.52c2.52,0 4.2,-0.84 5.88,-2.52l24.41,-24.41c30.46,28.22 70.69,43.72 112.4,43.72c92.33,0 167.87,-74.7 167.87,-167.87C419.67,159.48 344.13,83.93 251.8,83.93zM251.8,235.02c9.23,0 16.79,7.55 16.79,16.79c0,9.23 -7.55,16.79 -16.79,16.79c-4.18,0 -8.01,-1.56 -10.95,-4.11c-0.24,-0.32 -0.5,-0.63 -0.8,-0.93s-0.61,-0.56 -0.93,-0.8c-2.55,-2.95 -4.11,-6.77 -4.11,-10.95C235.02,242.57 242.57,235.02 251.8,235.02z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M92.33,159.48c0,-9.23 -7.55,-16.79 -16.79,-16.79s-16.79,7.55 -16.79,16.79s7.55,16.79 16.79,16.79S92.33,168.71 92.33,159.48z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M318.95,327.34c0,9.23 7.55,16.79 16.79,16.79c9.23,0 16.79,-7.55 16.79,-16.79c0,-9.23 -7.55,-16.79 -16.79,-16.79C326.51,310.56 318.95,318.11 318.95,327.34z" />
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M360.92,109.11c9.23,0 16.79,-7.55 16.79,-16.79s-7.55,-16.79 -16.79,-16.79s-16.79,7.55 -16.79,16.79S351.68,109.11 360.92,109.11z" />
|
||||
</vector>
|
||||
@@ -1,242 +0,0 @@
|
||||
<?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"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:transitionGroup="true"
|
||||
android:keepScreenOn="true">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/map_toolbar"
|
||||
style="@style/Toolbar"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/map_btn_back"
|
||||
style="@style/ToolbarButton"
|
||||
android:layout_gravity="start|center_vertical"
|
||||
android:contentDescription="@string/btn_back"
|
||||
android:src="@drawable/ic_back" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_timer"
|
||||
style="@style/ToolbarTimer" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/map_card"
|
||||
style="@style/SurfaceCard"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="@dimen/view_default_margin"
|
||||
android:layout_marginTop="@dimen/view_default_margin"
|
||||
android:layout_marginEnd="@dimen/view_default_margin"
|
||||
android:layout_marginBottom="@dimen/view_default_margin"
|
||||
app:layout_constraintBottom_toTopOf="@+id/map_card_info"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/map_toolbar">
|
||||
|
||||
<org.osmdroid.views.MapView
|
||||
android:id="@+id/map_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_copyright"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="2dp"
|
||||
android:layout_marginTop="2dp"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:text="@string/map_copyright"
|
||||
android:textColor="@color/textMain"
|
||||
android:textSize="@dimen/text_size_copyright"
|
||||
app:layout_constraintEnd_toEndOf="@+id/map_card"
|
||||
app:layout_constraintStart_toStartOf="@+id/map_card"
|
||||
app:layout_constraintTop_toTopOf="@+id/map_card" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/map_card_info"
|
||||
style="@style/SurfaceCard"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="@dimen/view_default_margin"
|
||||
android:layout_marginEnd="@dimen/view_default_margin"
|
||||
android:layout_marginBottom="@dimen/view_default_margin"
|
||||
app:layout_constraintBottom_toTopOf="@+id/map_coordinator"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_azimuth"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/map_azimuth"
|
||||
app:layout_constraintBottom_toTopOf="@+id/map_data_alt"
|
||||
app:layout_constraintStart_toStartOf="@+id/map_data_period"
|
||||
app:layout_constraintTop_toBottomOf="@+id/map_data_period" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_lat"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/map_latitude"
|
||||
app:layout_constraintBottom_toTopOf="@+id/map_data_qth"
|
||||
app:layout_constraintStart_toStartOf="@+id/map_data_alt"
|
||||
app:layout_constraintTop_toBottomOf="@+id/map_data_alt" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_lon"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/map_longitude"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_data_lat"
|
||||
app:layout_constraintEnd_toEndOf="@+id/map_data_dst" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_alt"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/map_altitude"
|
||||
app:layout_constraintBottom_toTopOf="@+id/map_data_lat"
|
||||
app:layout_constraintStart_toStartOf="@+id/map_azimuth"
|
||||
app:layout_constraintTop_toBottomOf="@+id/map_azimuth" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_dst"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/map_distance"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_data_alt"
|
||||
app:layout_constraintEnd_toEndOf="@+id/map_elevation" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_elevation"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/map_elevation"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_azimuth"
|
||||
app:layout_constraintEnd_toEndOf="@+id/map_data_phase" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_period"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:text="@string/map_period"
|
||||
app:layout_constraintBottom_toTopOf="@+id/map_azimuth"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_phase"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:text="@string/map_phase"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_data_period"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_qth"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:text="@string/map_qth"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/map_data_lat"
|
||||
app:layout_constraintTop_toBottomOf="@+id/map_data_lat" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_vel"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/map_velocity"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_data_qth"
|
||||
app:layout_constraintEnd_toEndOf="@+id/map_data_lon" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/map_coordinator"
|
||||
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">
|
||||
|
||||
<com.google.android.material.bottomappbar.BottomAppBar
|
||||
android:id="@+id/map_bottom_bar"
|
||||
style="@style/BottomBar" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/map_btn_prev"
|
||||
style="@style/NormalButton"
|
||||
android:layout_width="@dimen/button_width_max"
|
||||
android:layout_marginStart="@dimen/button_margin_side"
|
||||
android:text="@string/btn_prev"
|
||||
app:icon="@drawable/ic_prev"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/map_coordinator"
|
||||
app:layout_constraintStart_toStartOf="@+id/map_coordinator"
|
||||
app:layout_constraintTop_toTopOf="@+id/map_coordinator" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/map_data_visibility"
|
||||
style="@style/WorldMapText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginEnd="4dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_horizontal"
|
||||
android:maxLines="1"
|
||||
android:text="@string/map_visible"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_btn_prev"
|
||||
app:layout_constraintEnd_toStartOf="@+id/map_btn_next"
|
||||
app:layout_constraintStart_toEndOf="@+id/map_btn_prev" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/map_btn_next"
|
||||
style="@style/NormalButton"
|
||||
android:layout_width="@dimen/button_width_max"
|
||||
android:layout_marginEnd="@dimen/button_margin_side"
|
||||
android:text="@string/btn_next"
|
||||
app:icon="@drawable/ic_next"
|
||||
app:iconGravity="end"
|
||||
app:layout_constraintBaseline_toBaselineOf="@+id/map_btn_prev"
|
||||
app:layout_constraintEnd_toEndOf="@+id/map_coordinator" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.osmdroid.views.MapView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/osm_map_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/nav_entries"
|
||||
android:icon="@drawable/ic_satellite"
|
||||
android:title="@string/menu_satellites" />
|
||||
<item
|
||||
android:id="@+id/nav_passes"
|
||||
android:icon="@drawable/ic_list"
|
||||
android:title="@string/menu_passes" />
|
||||
<item
|
||||
android:id="@+id/nav_map"
|
||||
android:icon="@drawable/ic_map"
|
||||
android:title="@string/menu_map" />
|
||||
<item
|
||||
android:id="@+id/nav_settings"
|
||||
android:icon="@drawable/ic_settings"
|
||||
android:title="@string/menu_settings" />
|
||||
</menu>
|
||||
@@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation 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:id="@+id/nav_root"
|
||||
app:startDestination="@id/nav_radar">
|
||||
<fragment
|
||||
android:id="@+id/nav_radar"
|
||||
android:name="com.rtbishop.look4sat.presentation.radarScreen.RadarFragment"
|
||||
tools:layout="@layout/fragment_radar">
|
||||
<argument
|
||||
android:name="catNum"
|
||||
android:defaultValue="-1"
|
||||
app:argType="integer" />
|
||||
<argument
|
||||
android:name="aosTime"
|
||||
android:defaultValue="0L"
|
||||
app:argType="long" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/nav_map"
|
||||
android:name="com.rtbishop.look4sat.presentation.mapScreen.MapFragment"
|
||||
tools:layout="@layout/fragment_map">
|
||||
<argument
|
||||
android:name="catNum"
|
||||
android:defaultValue="-1"
|
||||
app:argType="integer" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/nav_settings"
|
||||
android:name="com.rtbishop.look4sat.presentation.settingsScreen.SettingsFragment"
|
||||
tools:layout="@layout/fragment_settings" />
|
||||
<dialog
|
||||
android:id="@+id/nav_modes"
|
||||
android:name="com.rtbishop.look4sat.presentation.entriesScreen.ModesDialog"
|
||||
tools:layout="@layout/dialog_modes" />
|
||||
<dialog
|
||||
android:id="@+id/nav_position"
|
||||
android:name="com.rtbishop.look4sat.presentation.settingsScreen.PositionDialog"
|
||||
tools:layout="@layout/dialog_position" />
|
||||
<dialog
|
||||
android:id="@+id/nav_locator"
|
||||
android:name="com.rtbishop.look4sat.presentation.settingsScreen.LocatorDialog"
|
||||
tools:layout="@layout/dialog_locator" />
|
||||
<action
|
||||
android:id="@+id/global_to_entries"
|
||||
app:destination="@id/nav_entries"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<action
|
||||
android:id="@+id/global_to_passes"
|
||||
app:destination="@id/nav_passes"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<action
|
||||
android:id="@+id/global_to_radar"
|
||||
app:destination="@id/nav_radar"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<action
|
||||
android:id="@+id/global_to_map"
|
||||
app:destination="@id/nav_map"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<action
|
||||
android:id="@+id/global_to_settings"
|
||||
app:destination="@id/nav_settings"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<action
|
||||
android:id="@+id/global_to_position"
|
||||
app:destination="@id/nav_position"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
<action
|
||||
android:id="@+id/global_to_locator"
|
||||
app:destination="@id/nav_locator"
|
||||
app:enterAnim="@anim/nav_default_enter_anim"
|
||||
app:exitAnim="@anim/nav_default_exit_anim"
|
||||
app:popEnterAnim="@anim/nav_default_pop_enter_anim"
|
||||
app:popExitAnim="@anim/nav_default_pop_exit_anim" />
|
||||
</navigation>
|
||||
Reference in new issue
Block a user