SavedStateHandle, возвращающий нулевые значения - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть значок меню 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
    }

}
...