BUGFIX: opening CanteenFragment.kt more than once would disallow refreshing from working properly

BUGFIX: fragments launch slowly when quickly clicking through the bottom navigation view
This commit is contained in:
denizk0461
2023-04-26 19:49:29 +02:00
parent 450ce92dca
commit 939bc06441
3 changed files with 34 additions and 52 deletions
@@ -3,7 +3,6 @@ package com.denizk0461.studip.activity
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentTransaction import androidx.fragment.app.FragmentTransaction
import androidx.lifecycle.Lifecycle import androidx.lifecycle.Lifecycle
import com.denizk0461.studip.R import com.denizk0461.studip.R
@@ -21,14 +20,12 @@ class MainActivity : AppCompatActivity() {
// View binding // View binding
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
/* /*
* ID of the bottom navigation view button that launched the currently active fragment; set on * Tag for the currently active fragment; set on activity launch to the fragment that will be
* activity launch to the fragment that will be first shown * shown first.
*/ */
private var currentFragment: Int = R.id.plan private var currentFragment: String = "event"
// All fragments are instantiated at app launch
private val fragments: List<Fragment> =
listOf(EventFragment(), CanteenFragment(), SettingsFragment())
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
@@ -44,12 +41,15 @@ class MainActivity : AppCompatActivity() {
binding = ActivityMainBinding.inflate(layoutInflater) binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root) setContentView(binding.root)
/* // Set up navigation view bar to launch fragments
* Set up navigation view bar to launch fragments.
* TODO: why do fragments launch slowly when quickly clicking between them?
*/
binding.contentMain.navView.setOnItemSelectedListener { item -> binding.contentMain.navView.setOnItemSelectedListener { item ->
loadFragment(item.itemId)
// Launch fragment based on the item that has been clicked
loadFragment(when (item.itemId) {
R.id.food -> "canteen"
R.id.settings -> "settings"
else -> "event"
})
} }
// Launch the fragment defined in currentFragment // Launch the fragment defined in currentFragment
@@ -59,56 +59,38 @@ class MainActivity : AppCompatActivity() {
/** /**
* Loads a given fragment. * Loads a given fragment.
* *
* @param id the ID of the bottom navigation view button that was clicked * @param type tag for the fragment that is to be opened
* @return true on success, false if another fragment is currently instantiating * @return true on success, false if another fragment is currently instantiating
*/ */
private fun loadFragment(id: Int): Boolean { private fun loadFragment(type: String): Boolean {
// Get fragment to be loaded
val fragment = getFragment(id)
// Check if another fragment exists and is not fully initialised // Find the fragment that is to be opened, or create it if it hasn't been instantiated yet
val fragment = supportFragmentManager.findFragmentByTag(type) ?: getFragment(type)
// Don't interrupt the current fragment's lifecycle if it isn't fully initialised
if (fragment.lifecycle.currentState != Lifecycle.State.INITIALIZED) { if (fragment.lifecycle.currentState != Lifecycle.State.INITIALIZED) {
// Return false to avoid interrupting the fragment's lifecycle
return false return false
} }
// Prepare and commit a transaction between the current and the next fragment // Start the transaction to show the new fragment
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment_content_main, fragment, id.toString()) .replace(R.id.nav_host_fragment_content_main, fragment, type)
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE) .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
// .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
.commit() .commit()
// Set text of the app bar accordingly // Success
// binding.contentMain.appTitleBar.text = getTitleString(id)
// Note down the new current fragment
currentFragment = id
// Transaction successful
return true return true
} }
/** /**
* Retrieve fragment by the ID of the bottom navigation view's button. * Retrieve fragment by its tag.
* *
* @param id the ID of the bottom navigation button * @param type tag for the corresponding fragment
* @return the corresponding fragment * @return the corresponding fragment
*/ */
private fun getFragment(id: Int) = when (id) { private fun getFragment(type: String) = when (type) {
R.id.food -> fragments[1] // CanteenFragment.kt "canteen" -> CanteenFragment() // CanteenFragment.kt
R.id.settings -> fragments[2] // SettingsFragment.kt "settings" -> SettingsFragment() // SettingsFragment.kt
else -> fragments[0] // on unknown value or R.id.plan, launch EventFragment.kt else -> EventFragment() // on unknown value or "event", launch EventFragment.kt
}
/**
* Retrieve app bar text by the ID of the bottom navigation view's button.
*
* @param id the ID of the bottom navigation button
* @return the corresponding fragment's title
*/
private fun getTitleString(id: Int) = when (id) {
R.id.food -> getString(R.string.title_food)
R.id.settings -> getString(R.string.title_settings)
else -> getString(R.string.title_schedule) // on unknown value or R.id.plan, get text for EventFragment.kt
} }
} }
@@ -1,6 +1,5 @@
package com.denizk0461.studip.data package com.denizk0461.studip.data
import com.denizk0461.studip.R
import com.denizk0461.studip.db.AppRepository import com.denizk0461.studip.db.AppRepository
import com.denizk0461.studip.model.* import com.denizk0461.studip.model.*
import org.jsoup.Jsoup import org.jsoup.Jsoup
@@ -173,12 +173,6 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
// Set the text for the opening hours dialogue // Set the text for the opening hours dialogue
openingHours = viewModel.getCanteenOpeningHours() openingHours = viewModel.getCanteenOpeningHours()
/*
* Tell the swipe refresh layout to stop refreshing.
* TODO if an exception is raised, this will not be fired. This must be changed
*/
binding.swipeRefreshLayout.isRefreshing = false
} }
// Set up functions for when the user swipes to refresh the view // Set up functions for when the user swipes to refresh the view
@@ -352,6 +346,13 @@ class CanteenFragment : AppFragment(), CanteenOfferItemAdapter.OnClickListener {
viewModel.fetchOffers(viewModel.preferenceCanteen, onRefreshUpdate = { status -> viewModel.fetchOffers(viewModel.preferenceCanteen, onRefreshUpdate = { status ->
// TODO refresh updates // TODO refresh updates
}, onFinish = { }, onFinish = {
/*
* Tell the swipe refresh layout to stop refreshing.
* TODO if an exception is raised, this will not be fired. This must be changed
*/
binding.swipeRefreshLayout.isRefreshing = false
// createTabLayoutMediator() // createTabLayoutMediator()
// binding.swipeRefreshLayout.isRefreshing = false // binding.swipeRefreshLayout.isRefreshing = false
// createTabLayoutMediator() // createTabLayoutMediator()