Significantly revamped the recycler behaviour. Now accurately showing the satellites currently overhead and their pass progress, removing them from the list after the pass is finished.

This commit is contained in:
Arty Bishop committed 2020-01-12 10:37:41 +00:00
1 parent c68eff90a5
commit efdb9fe7fc
4 files changed
+49 -23

No files matched your search

@@ -65,8 +65,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
private val _debugMessage = MutableLiveData<String>() private val _debugMessage = MutableLiveData<String>()
val debugMessage: LiveData<String> = _debugMessage val debugMessage: LiveData<String> = _debugMessage
private val _satPassList = MutableLiveData<List<SatPass>>() private val _satPassList = MutableLiveData<MutableList<SatPass>>()
val passSatList: LiveData<List<SatPass>> = _satPassList val passSatList: LiveData<MutableList<SatPass>> = _satPassList
private val _gsp = MutableLiveData<GroundStationPosition>() private val _gsp = MutableLiveData<GroundStationPosition>()
val gsp: LiveData<GroundStationPosition> = _gsp val gsp: LiveData<GroundStationPosition> = _gsp
@@ -181,6 +181,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
suspend fun getPasses() { suspend fun getPasses() {
val passList = mutableListOf<SatPass>() val passList = mutableListOf<SatPass>()
val dateNow = Date() val dateNow = Date()
val dateFuture = Calendar.getInstance().let {
it.time = dateNow
it.add(Calendar.HOUR, hoursAhead)
it.time
}
withContext(Dispatchers.Default) { withContext(Dispatchers.Default) {
tleSelection.forEach { indexOfSelection -> tleSelection.forEach { indexOfSelection ->
val tle = tleMainList[indexOfSelection] val tle = tleMainList[indexOfSelection]
@@ -194,6 +199,7 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
_debugMessage.postValue("${tle.name} shall not pass") _debugMessage.postValue("${tle.name} shall not pass")
} }
} }
passList.removeAll { it.pass.startTime.after(dateFuture) }
passList.removeAll { it.pass.endTime.before(dateNow) } passList.removeAll { it.pass.endTime.before(dateNow) }
passList.removeAll { it.pass.maxEl < minEl } passList.removeAll { it.pass.maxEl < minEl }
passList.sortBy { it.pass.startTime } passList.sortBy { it.pass.startTime }
@@ -30,5 +30,6 @@ import kotlinx.android.parcel.RawValue
data class SatPass( data class SatPass(
val tle: TLE, val tle: TLE,
val predictor: @RawValue PassPredictor, val predictor: @RawValue PassPredictor,
val pass: @RawValue SatPassTime val pass: @RawValue SatPassTime,
var progress: Int = 0
) : Parcelable ) : Parcelable
@@ -33,10 +33,34 @@ import java.util.*
class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.PassHolder>() { class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.PassHolder>() {
private var satPassList = emptyList<SatPass>() private var satPassList = mutableListOf<SatPass>()
fun setList(list: List<SatPass>) { fun setList(list: MutableList<SatPass>) {
satPassList = list satPassList = list
notifyDataSetChanged()
}
fun updateRecycler() {
val timeNow = Date()
val iterator = satPassList.listIterator()
while (iterator.hasNext()) {
val satPass = iterator.next()
if (satPass.progress < 100) {
val timeStart = satPass.pass.startTime
val timeEnd = satPass.pass.endTime
if (timeNow.after(timeStart)) {
val index = satPassList.indexOf(satPass)
val deltaTotal = timeEnd.time.minus(timeStart.time)
val deltaNow = timeNow.time.minus(timeStart.time)
satPass.progress = ((deltaNow.toFloat() / deltaTotal.toFloat()) * 100).toInt()
notifyItemChanged(index)
}
} else {
val index = satPassList.indexOf(satPass)
iterator.remove()
notifyItemRemoved(index)
}
}
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
@@ -51,7 +75,7 @@ class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.PassHolder>() {
} }
override fun onBindViewHolder(holder: PassHolder, position: Int) { override fun onBindViewHolder(holder: PassHolder, position: Int) {
holder.bind(position) holder.bind(satPassList[position])
} }
inner class PassHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { inner class PassHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@@ -62,11 +86,9 @@ class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.PassHolder>() {
private val passVector = itemView.findViewById<TextView>(R.id.pass_azVector) private val passVector = itemView.findViewById<TextView>(R.id.pass_azVector)
private val passStart = itemView.findViewById<TextView>(R.id.pass_aosTime) private val passStart = itemView.findViewById<TextView>(R.id.pass_aosTime)
private val passEnd = itemView.findViewById<TextView>(R.id.pass_losTime) private val passEnd = itemView.findViewById<TextView>(R.id.pass_losTime)
var progressBar = itemView.findViewById<ProgressBar>(R.id.pass_progress) private var progressBar = itemView.findViewById<ProgressBar>(R.id.pass_progress)
fun bind(position: Int) {
val satPass = satPassList[position]
fun bind(satPass: SatPass) {
val aosTime = val aosTime =
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.startTime) SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.startTime)
val losTime = val losTime =
@@ -78,6 +100,7 @@ class SatPassAdapter : RecyclerView.Adapter<SatPassAdapter.PassHolder>() {
String.format("Az: %2d° -> %2d°", satPass.pass.aosAzimuth, satPass.pass.losAzimuth) String.format("Az: %2d° -> %2d°", satPass.pass.aosAzimuth, satPass.pass.losAzimuth)
passStart.text = String.format("AOS - %s", aosTime) passStart.text = String.format("AOS - %s", aosTime)
passEnd.text = String.format("LOS - %s", losTime) passEnd.text = String.format("LOS - %s", losTime)
progressBar.progress = satPass.progress
itemView.setOnClickListener { itemView.setOnClickListener {
val action = SkyFragmentDirections.actionNavSkyToNavRadar(satPass) val action = SkyFragmentDirections.actionNavSkyToNavRadar(satPass)
@@ -35,6 +35,7 @@ import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.github.amsacode.predict4java.TLE import com.github.amsacode.predict4java.TLE
import com.google.android.material.floatingactionbutton.FloatingActionButton import com.google.android.material.floatingactionbutton.FloatingActionButton
@@ -43,6 +44,7 @@ import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.repo.SatPass import com.rtbishop.look4sat.repo.SatPass
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import java.util.*
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
class SkyFragment : Fragment() { class SkyFragment : Fragment() {
@@ -56,7 +58,7 @@ class SkyFragment : Fragment() {
private lateinit var aosTimer: CountDownTimer private lateinit var aosTimer: CountDownTimer
private lateinit var swipeLayout: SwipeRefreshLayout private lateinit var swipeLayout: SwipeRefreshLayout
private lateinit var mainActivity: MainActivity private lateinit var mainActivity: MainActivity
private lateinit var satPassList: List<SatPass> private lateinit var satPassList: MutableList<SatPass>
private var isTimerSet: Boolean = false private var isTimerSet: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
@@ -64,7 +66,7 @@ class SkyFragment : Fragment() {
mainActivity = activity as MainActivity mainActivity = activity as MainActivity
viewModel = ViewModelProvider(mainActivity).get(MainViewModel::class.java) viewModel = ViewModelProvider(mainActivity).get(MainViewModel::class.java)
recyclerAdapter = SatPassAdapter() recyclerAdapter = SatPassAdapter()
satPassList = emptyList() satPassList = mutableListOf()
} }
override fun onCreateView( override fun onCreateView(
@@ -92,9 +94,9 @@ class SkyFragment : Fragment() {
recyclerPasses.apply { recyclerPasses.apply {
layoutManager = LinearLayoutManager(mainActivity) layoutManager = LinearLayoutManager(mainActivity)
adapter = recyclerAdapter adapter = recyclerAdapter
(itemAnimator as SimpleItemAnimator).supportsChangeAnimations = false
} }
recyclerAdapter.setList(satPassList) recyclerAdapter.setList(satPassList)
recyclerAdapter.notifyDataSetChanged()
setTimerForNextPass() setTimerForNextPass()
swipeLayout.setProgressBackgroundColorSchemeResource(R.color.themeAccent) swipeLayout.setProgressBackgroundColorSchemeResource(R.color.themeAccent)
@@ -112,7 +114,6 @@ class SkyFragment : Fragment() {
viewModel.passSatList.observe(viewLifecycleOwner, Observer { viewModel.passSatList.observe(viewLifecycleOwner, Observer {
satPassList = it satPassList = it
recyclerAdapter.setList(satPassList) recyclerAdapter.setList(satPassList)
recyclerAdapter.notifyDataSetChanged()
setTimerForNextPass() setTimerForNextPass()
swipeLayout.isRefreshing = false swipeLayout.isRefreshing = false
}) })
@@ -210,18 +211,12 @@ class SkyFragment : Fragment() {
if (satPassList.isNotEmpty()) { if (satPassList.isNotEmpty()) {
resetTimer() resetTimer()
try { try {
val timeNow = System.currentTimeMillis() val timeNow = Date()
val nextPass = satPassList.first { val nextPass = satPassList.first { it.pass.startTime.after(timeNow) }
it.pass.startTime.time.minus(timeNow) > 0 val totalMillis = nextPass.pass.startTime.time.minus(timeNow.time)
}
val passTime = nextPass.pass.startTime.time
val totalMillis = passTime.minus(timeNow)
aosTimer = object : CountDownTimer(totalMillis, 1000) { aosTimer = object : CountDownTimer(totalMillis, 1000) {
override fun onFinish() { override fun onFinish() {
Toast
.makeText(activity, "Incoming ${nextPass.tle.name}", Toast.LENGTH_SHORT)
.show()
setTimerForNextPass() setTimerForNextPass()
} }
@@ -232,6 +227,7 @@ class SkyFragment : Fragment() {
TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60, TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished) % 60,
TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60 TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) % 60
) )
recyclerAdapter.updateRecycler()
} }
} }
aosTimer.start() aosTimer.start()