Further changes to layouts and fragments

This commit is contained in:
Arty Bishop committed 2022-01-22 20:36:59 +00:00
1 parent f34cb8eb3c
commit f9ebe84012
23 files changed
+414 -500

No files matched your search

@@ -1,44 +0,0 @@
/*
* Look4Sat. Amateur radio satellite tracker and pass predictor.
* Copyright (C) 2019-2021 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
import android.graphics.Canvas
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
class ItemDivider(private val resId: Int) : RecyclerView.ItemDecoration() {
override fun onDrawOver(canvas: Canvas, parent: RecyclerView) {
ContextCompat.getDrawable(parent.context, resId)?.let { drawable ->
val leftPos = parent.paddingLeft
val rightPos = parent.width - parent.paddingRight
parent.adapter?.itemCount?.let { childCount ->
for (i in 0 until childCount) {
if (i == (childCount - 1)) continue
parent.getChildAt(i)?.let { view ->
val params = view.layoutParams as RecyclerView.LayoutParams
val topPos = view.bottom + params.bottomMargin
val bottomPos = topPos + drawable.intrinsicHeight
drawable.setBounds(leftPos, topPos, rightPos, bottomPos)
drawable.draw(canvas)
}
}
}
}
}
}
@@ -22,9 +22,6 @@ import android.content.pm.ActivityInfo
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.ActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
@@ -36,9 +33,6 @@ class Look4SatActivity : AppCompatActivity() {
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
super.onCreate(savedInstanceState)
installSplashScreen()
val binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val navHost = supportFragmentManager.findFragmentById(R.id.main_nav_host) as NavHostFragment
binding.mainNavBottom.setupWithNavController(navHost.navController)
setContentView(ActivityMainBinding.inflate(layoutInflater).root)
}
}
@@ -31,7 +31,6 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.FragmentEntriesBinding
import com.rtbishop.look4sat.domain.model.DataState
import com.rtbishop.look4sat.domain.model.SatItem
import com.rtbishop.look4sat.presentation.ItemDivider
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
@@ -52,7 +51,7 @@ class EntriesFragment : Fragment(R.layout.fragment_entries) {
adapter = entriesAdapter
layoutManager = GridLayoutManager(requireContext(), 2)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(ItemDivider(R.drawable.divider_dark))
// addItemDecoration(ItemDivider(R.drawable.divider_dark))
}
entriesBack.setOnClickListener { findNavController().navigateUp() }
entriesSearch.doOnTextChanged { text, _, _, _ -> viewModel.setQuery(text.toString()) }
@@ -23,8 +23,7 @@ import androidx.recyclerview.widget.AsyncListDiffer
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.ItemPassGeoBinding
import com.rtbishop.look4sat.databinding.ItemPassLeoBinding
import com.rtbishop.look4sat.databinding.ItemPassBinding
import com.rtbishop.look4sat.domain.predict.SatPass
import java.text.SimpleDateFormat
import java.util.*
@@ -53,56 +52,57 @@ class PassesAdapter(private val isUTC: Boolean, private val clickListener: Passe
override fun getItemCount() = differ.currentList.size
override fun getItemViewType(position: Int): Int {
return if (differ.currentList[position].isDeepSpace) 1
else 0
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return if (viewType == 0) {
SatPassLeoHolder.from(parent)
} else {
SatPassGeoHolder.from(parent)
}
return PassHolder.from(parent)
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder.itemViewType == 0) {
(holder as SatPassLeoHolder).bind(differ.currentList[position], clickListener, isUTC)
} else {
(holder as SatPassGeoHolder).bind(differ.currentList[position], clickListener)
}
(holder as PassHolder).bind(differ.currentList[position], clickListener, isUTC)
}
class SatPassLeoHolder private constructor(private val binding: ItemPassLeoBinding) :
class PassHolder private constructor(private val binding: ItemPassBinding) :
RecyclerView.ViewHolder(binding.root) {
private val satIdFormat = itemView.context.getString(R.string.pass_satId)
private val tcaAzFormat = itemView.context.getString(R.string.pass_tcaAz)
private val aosAzFormat = itemView.context.getString(R.string.pass_aosAz)
private val maxElFormat = itemView.context.getString(R.string.pass_maxEl)
private val losAzFormat = itemView.context.getString(R.string.pass_losAz)
private val altFormat = itemView.context.getString(R.string.pass_altitude)
private val losAzFormat = itemView.context.getString(R.string.pass_los)
private val startTimeFormat = itemView.context.getString(R.string.pass_startTime)
private val elevFormat = itemView.context.getString(R.string.pat_elevation)
private val maxElFormat = itemView.context.getString(R.string.pass_elevation)
private val endTimeFormat = itemView.context.getString(R.string.pass_endTime)
private val placeholder = itemView.context.getString(R.string.pass_placeholder)
private val timeZoneUTC = TimeZone.getTimeZone("UTC")
private val startFormat = SimpleDateFormat(startTimeFormat, Locale.getDefault())
private val endFormat = SimpleDateFormat(endTimeFormat, Locale.getDefault())
fun bind(satPass: SatPass, listener: PassesClickListener, shouldUseUTC: Boolean) {
binding.apply {
if (shouldUseUTC) {
startFormat.timeZone = timeZoneUTC
endFormat.timeZone = timeZoneUTC
if (satPass.isDeepSpace) {
passName.text = satPass.name
passId.text = String.format(satIdFormat, satPass.catNum)
passAos.text = String.format(aosAzFormat, satPass.aosAzimuth)
passAltitude.text = String.format(altFormat, satPass.altitude)
passLos.text = String.format(losAzFormat, satPass.losAzimuth)
passStart.text = placeholder
passElev.text = String.format(elevFormat, satPass.maxElevation)
passEnd.text = placeholder
passProgress.progress = 100
} else {
if (shouldUseUTC) {
startFormat.timeZone = timeZoneUTC
endFormat.timeZone = timeZoneUTC
}
passName.text = satPass.name
passId.text = String.format(satIdFormat, satPass.catNum)
passAos.text = String.format(aosAzFormat, satPass.aosAzimuth)
passAltitude.text = String.format(altFormat, satPass.altitude)
passLos.text = String.format(losAzFormat, satPass.losAzimuth)
passStart.text = startFormat.format(Date(satPass.aosTime))
passElev.text = String.format(maxElFormat, satPass.maxElevation)
passEnd.text = endFormat.format(Date(satPass.losTime))
passProgress.progress = satPass.progress
}
passLeoName.text = satPass.name
passLeoId.text = String.format(satIdFormat, satPass.catNum)
passLeoAos.text = String.format(aosAzFormat, satPass.aosAzimuth)
passLeoElev.text = String.format(maxElFormat, satPass.maxElevation)
passLeoLos.text = String.format(losAzFormat, satPass.losAzimuth)
passLeoStart.text = startFormat.format(Date(satPass.aosTime))
passLeoTca.text = String.format(tcaAzFormat, satPass.tcaAzimuth)
passLeoEnd.text = endFormat.format(Date(satPass.losTime))
passLeoProgress.progress = satPass.progress
}
itemView.setOnClickListener {
@@ -111,39 +111,9 @@ class PassesAdapter(private val isUTC: Boolean, private val clickListener: Passe
}
companion object {
fun from(parent: ViewGroup): SatPassLeoHolder {
fun from(parent: ViewGroup): PassHolder {
val inflater = LayoutInflater.from(parent.context)
return SatPassLeoHolder(ItemPassLeoBinding.inflate(inflater, parent, false))
}
}
}
class SatPassGeoHolder private constructor(private val binding: ItemPassGeoBinding) :
RecyclerView.ViewHolder(binding.root) {
private val satIdFormat = itemView.context.getString(R.string.pass_satId)
private val azFormat = itemView.context.getString(R.string.pat_azimuth)
private val altFormat = itemView.context.getString(R.string.pat_altitude)
private val elevFormat = itemView.context.getString(R.string.pat_elevation)
fun bind(satPass: SatPass, listener: PassesClickListener) {
binding.apply {
passGeoName.text = satPass.name
passGeoId.text = String.format(satIdFormat, satPass.catNum)
passGeoAz.text = String.format(azFormat, satPass.tcaAzimuth)
passGeoAlt.text = String.format(altFormat, satPass.altitude)
passGeoEl.text = String.format(elevFormat, satPass.maxElevation)
}
itemView.setOnClickListener {
listener.navigateToPass(satPass)
}
}
companion object {
fun from(parent: ViewGroup): SatPassGeoHolder {
val inflater = LayoutInflater.from(parent.context)
return SatPassGeoHolder(ItemPassGeoBinding.inflate(inflater, parent, false))
return PassHolder(ItemPassBinding.inflate(inflater, parent, false))
}
}
}
@@ -30,7 +30,6 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.databinding.FragmentPassesBinding
import com.rtbishop.look4sat.domain.model.DataState
import com.rtbishop.look4sat.domain.predict.SatPass
import com.rtbishop.look4sat.presentation.ItemDivider
import com.rtbishop.look4sat.presentation.getNavResult
import com.rtbishop.look4sat.presentation.navigateSafe
import com.rtbishop.look4sat.presentation.toTimerString
@@ -50,13 +49,12 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
private fun setupComponents(view: View) {
val passesAdapter = PassesAdapter(passesViewModel.shouldUseUTC(), this)
val binding = FragmentPassesBinding.bind(view).apply {
passesRecycler.apply {
passesList.apply {
setHasFixedSize(true)
adapter = passesAdapter
isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(ItemDivider(R.drawable.divider_dark))
addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (dy > 0 && passesFab.visibility == View.VISIBLE) passesFab.hide()
@@ -91,27 +89,24 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC
passesAdapter.submitList(dataState.data)
binding.apply {
passesSwipe.isRefreshing = false
passesList.visibility = View.VISIBLE
passesError.visibility = View.INVISIBLE
passesProgress.visibility = View.INVISIBLE
passesRecycler.visibility = View.VISIBLE
}
tickMainTimer(dataState.data, binding)
}
is DataState.Loading -> {
binding.apply {
passesSwipe.isRefreshing = true
passesTimer.text = 0L.toTimerString()
passesSwipe.isRefreshing = true
passesList.visibility = View.INVISIBLE
passesError.visibility = View.INVISIBLE
passesRecycler.visibility = View.INVISIBLE
passesProgress.visibility = View.VISIBLE
}
}
else -> {
binding.apply {
passesSwipe.isRefreshing = false
passesTimer.text = 0L.toTimerString()
passesProgress.visibility = View.INVISIBLE
passesRecycler.visibility = View.INVISIBLE
passesSwipe.isRefreshing = false
passesList.visibility = View.INVISIBLE
passesError.visibility = View.VISIBLE
}
}
@@ -30,7 +30,6 @@ import com.rtbishop.look4sat.databinding.FragmentRadarBinding
import com.rtbishop.look4sat.domain.predict.SatPass
import com.rtbishop.look4sat.domain.predict.SatPos
import com.rtbishop.look4sat.framework.SettingsProvider
import com.rtbishop.look4sat.presentation.ItemDivider
import com.rtbishop.look4sat.presentation.navigateSafe
import com.rtbishop.look4sat.presentation.toTimerString
import dagger.hilt.android.AndroidEntryPoint
@@ -54,7 +53,7 @@ class RadarFragment : Fragment(R.layout.fragment_radar) {
isVerticalScrollBarEnabled = false
layoutManager = LinearLayoutManager(context)
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
addItemDecoration(ItemDivider(R.drawable.divider_dark))
// addItemDecoration(ItemDivider(R.drawable.divider_dark))
}
setupObservers(transAdapter, this)
}
@@ -135,7 +135,7 @@ class RadarView(context: Context) : View(context) {
isTrackCreated = true
}
canvas.drawColor(ContextCompat.getColor(context, R.color.surfaceBg))
canvas.drawColor(ContextCompat.getColor(context, R.color.surfaceCard))
drawRadarCircle(canvas, cx, cy, radarRadius)
drawRadarCross(canvas, cx, cy, radarRadius)
drawRadarText(canvas, cx, radarRadius)