У меня есть значок меню ActionBar
, который открывает CategoryFragment
. Этот фрагмент принимает аргумент category
object SafeArgs
, переданный из другого фрагмента. В CategoryFragment
я сохраняю имя и идентификатор category
в общих ViewModel
фрагмента как значения SavedStateHandle
. Я настроил его так, чтобы фрагмент использовал сохраненные значения SavedStateHandle
для имени категории и идентификатора, когда это необходимо. Например, CategoryFragment
впервые использует объект категории, переданный из отправляющего фрагмента, но при последующем создании CategoryFrgament
будут использоваться значения SavedStateHandle
.
Проблема в том, что если после сначала откройте CategoriesFragment
, а затем выйдите из приложения, нажав либо физическую кнопку возврата телефона, либо завершив работу приложения с помощью последней кнопки телефона на панели навигации, теперь открывая CategoryFragment
непосредственно, нажав значок меню ActionBar, чтобы отобразить пустой экран. Это потому, что значения, возвращаемые из SavedStateHandle
, являются нулевыми. Как я могу это исправить?
Фрагмент категории
class CategoryFragment : Fragment(), SearchView.OnQueryTextListener {
lateinit var navController: NavController
private var adapter: TasksRecyclerAdapter? = null
private val viewModel: CategoryTasksViewModel by activityViewModels()
private var fromCategoriesFragment: Boolean = false
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_category, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
navController = Navigation.findNavController(view)
observerSetup()
recyclerSetup()
var searchView = category_tasks_searchview
searchView.setOnQueryTextListener(this)
fab_new_task.setOnClickListener {
navController.navigate(R.id.action_categoryFragment_to_newTaskDialogFragment)
}
showTasks()
}
private fun showTasks() {
if(fromCategoriesFragment){
PomoPlayObservablesSingleton.fromCategoriesFragment.onNext(false)
if (!arguments?.isEmpty!!) {
var args = CategoryFragmentArgs.fromBundle(arguments!!)
category_title.text = args.category?.name
var category = args.category
viewModel.setPomoCategoryName(category.name)
viewModel.setCategoryId(category.id)
viewModel.searchTasksByCategoryId(category.id)
}
}
else{
category_title.text = viewModel.getPomoCategoryName()
viewModel.searchTasksByCategoryId(viewModel.getCategoryId())
Log.i("CategoryFrag-CatName", viewModel.getPomoCategoryName().toString())
Log.i("CategoryFrag-CatId", viewModel.getCategoryId().toString())
}
}
private fun observerSetup() {
viewModel.getSearchTasksByCategoryIdResults().observe(this,androidx.lifecycle.Observer { tasks ->
if(tasks.isNotEmpty()){
adapter?.setTasksList(tasks.sortedBy { task -> task.name?.toLowerCase() })
task_not_found_bubble.visibility = View.GONE
task_not_found_text.visibility = View.GONE
}
else{
task_not_found_bubble.visibility = View.VISIBLE
task_not_found_text.visibility = View.VISIBLE
}
})
PomoPlayObservablesSingleton.fromCategoriesFragment.subscribe {value -> fromCategoriesFragment = value}
}
private fun recyclerSetup() {
adapter = context?.let { TasksRecyclerAdapter(it) }
tasks_list?.layoutManager = LinearLayoutManager(context)
tasks_list?.adapter = adapter
}
override fun onQueryTextSubmit(query: String?): Boolean {
Log.i("Lifecycle-CatFragment", "onQueryTextSubmit() called")
var q = query?.toLowerCase()?.trim()?.replace("\\s+".toRegex(), " ")
setLastSearchQuery(q.toString())
viewModel.searchTasksByName(viewModel.getLastSearchQuery().toString())
return false
}
private fun setLastSearchQuery(lastSearchQuery: String) {
viewModel.setLastSearchQuery(lastSearchQuery)
}
}
CategoryTasksViewModel
class CategoryTasksViewModel(application: Application, state: SavedStateHandle) : AndroidViewModel(application) {
private val repository: PomoPlayRepository = PomoPlayRepository(application)
private val allCategories: LiveData<List<Category>>?
private val allPomoTasks: LiveData<List<PomoTask>>?
private val searchCategoriesByNameResults: MutableLiveData<List<Category>>
private val searchCategoryByIdResults: MutableLiveData<Category>
private val searchTasksByIdResults: MutableLiveData<PomoTask>
private val searchTasksByNameResults: MutableLiveData<List<PomoTask>>
private val searchTasksByCategoryIdResults: MutableLiveData<List<PomoTask>>
private val savedStateHandle = state
companion object{
private const val LAST_SEARCH_QUERY = "lastSearchQuery"
}
init {
allCategories = repository.allCategories
allPomoTasks = repository.allPomoTasks
searchTasksByIdResults = repository.searchTasksByIdResults
searchTasksByNameResults = repository.searchTasksByNameResults
searchTasksByCategoryIdResults = repository.searchTasksByCategoryIdResults
searchCategoryByIdResults = repository.searchCategoriesByIdResults
searchCategoriesByNameResults = repository.searchCategoriesByNameResults
}
fun setLastSearchQuery(lastSearchName: String){
savedStateHandle.set(LAST_SEARCH_QUERY, lastSearchName)
}
fun getLastSearchQuery(): String?{
return savedStateHandle.get<String>(LAST_SEARCH_QUERY)
}
fun setPomoCategoryName(name: String?){
savedStateHandle.set("categoryName", name)
}
fun getPomoCategoryName(): String?{
return savedStateHandle.get<String>("categoryName")
}
fun setCategoryId(id: Int){
savedStateHandle.set("categoryId", id)
}
fun getCategoryId(): Int?{
return savedStateHandle.get<Int>("categoryId")
}
fun insertTask(pomoTask: PomoTask?) {
repository.insertTask(pomoTask)
}
fun deleteTask(pomoTask: PomoTask) {
repository.deleteTask(pomoTask)
}
fun updateTask(pomoTask: PomoTask) {
repository.updateTask(pomoTask)
}
fun searchTasksByName(name: String) {
repository.searchTasksByName(name)
}
fun searchTasksById(pomoTaskId: Int){
repository.searchTasksById(pomoTaskId)
}
fun searchTasksByCategoryId(categoryId: Int?){
repository.searchTasksByCategoryId(categoryId)
}
fun getAllPomoTasks() : LiveData<List<PomoTask>>? {
return allPomoTasks
}
fun getSearchTasksbyNameResults() : MutableLiveData<List<PomoTask>> {
return searchTasksByNameResults
}
fun getSearchTasksByIdResults() : MutableLiveData<PomoTask> {
return searchTasksByIdResults
}
fun getSearchTasksByCategoryIdResults() : MutableLiveData<List<PomoTask>> {
return searchTasksByCategoryIdResults
}
}