- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 ActionBar
打开 CategoryFragment
的菜单图标.该 fragment 采用 category
对象 SafeArgs
从另一个 fragment 传递的参数。在 CategoryFragment
,我存储category
的名称和 id 进入 fragment 的共享 ViewModel
如SavedStateHandle
值(value)观。我已经设置它,以便 fragment 使用存储的 SavedStateHandle
需要时为类别名称和 id 设置值。例如,第一次使用 CategoryFragment
使用从发送 fragment 传递的类别对象,但随后创建 CategoryFrgament
将使用 SavedStateHandle
值(value)观。
问题是,如果在第一次打开 CategoriesFragment
然后通过按下手机的物理后退按钮或从导航栏中手机的最近按钮终止应用程序退出应用程序,现在打开 CategoryFragment
直接按ActionBar 菜单图标显示一个空白屏幕。这是因为从 SavedStateHandle
返回的值为空。我怎样才能解决这个问题?
分类 fragment
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)
}
}
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
}
}
最佳答案
SavedStateHandle
不是设计用来做的,你期望它做的事情:它......
... is a key-value map that will let you write and retrieve objectsto and from the saved state. These values will persist after theprocess is killed by the system and remain available via the sameobject.
The user's assumption in these complete dismissal cases is that theyhave permanently navigated away from the activity, and if they re-openthe activity they expect the activity to start from a clean state. Theunderlying system behavior for these dismissal scenarios matches theuser expectation - the activity instance will get destroyed andremoved from memory, along with any state stored in it and any savedinstance state record associated with the activity.
关于android - SavedStateHandle 返回空值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60066753/
这更像是一个概念性问题。 Android 最近在 viewModel 中引入了在进程死亡期间处理状态的概念,而不是以前用于 Activity 或 Fragment 中的 savedInstanceSt
我有一个 ActionBar打开 CategoryFragment 的菜单图标.该 fragment 采用 category对象 SafeArgs从另一个 fragment 传递的参数。在 Categ
我按照下一页中的说明创建了一个 viewModel,但是当我关闭应用程序并再次打开它时,SavedStateHandle 不起作用。 这是页面: Saved State module for View
我有两个选项可以在 fragment 之间传递数据,导航的安全参数和 View 模型的 SavedStateHandle,它们之间有什么区别以及如何在正确的位置使用它们? 最佳答案 关于这个问题的讨论
我有一个 ViewModel,它采用 SavedStateHandle范围。我在其中保存一个字符串,如下所示: private fun saveString(str: String) {
我有一个加载一堆请求的屏幕,并在同一屏幕和一个外部 WebView 上从用户那里收集一些数据。因此,我有一个包含这些复杂请求对象(+ 用户输入数据)的 ViewModel。我需要通过系统启动的进程死亡
我有单个 Activity 应用程序和 fragment 数。其中一些 fragment 正在使用我的 View 模型,通常是这样的: private val myViewModel: MyViewM
在 Android ViewModel 中,如何编写单元测试来验证 savedStateHandle 是否正确保存和恢复值? class SampleViewModel( private va
我正在尝试使用 savedStateHandle 测试这个 ViewModel class PostListViewModel @ViewModelInject constructor( pr
我正在尝试使用以下代码: suspend fun SavedStateHandle.getStateFlow( key: String, initialValue: T? = get
我有一个 ViewModel 类如下(简化以演示我面临的问题) class MyViewModel(private val savedStateHandle: SavedStateHandle) :
我是一名优秀的程序员,十分优秀!