我正在尝试在我现有的应用程序中使用Jetpack的架构组件实现导航。
我有一个单一的活动应用程序,其中主要片段(ListFragment)是一个项目列表。目前,当用户点击列表项时,通过fragmentTransaction将第二个片段添加到堆栈中。添加(R.id.main,detailFragment)
。因此,当按下back时,将分离细节片段,并再次显示ListFragment。
对于导航架构,这是自动处理的。不是添加它被替换的新片段,因此片段视图被销毁,而是在按下back以重新创建视图时调用onDestRoyView()
和onCreateView()
。
我知道这是一个很好的模式,用于LiveData和ViewModel,以避免使用超过必要的内存,但在我的情况下,这是恼人的,因为列表有一个复杂的布局,膨胀它是耗时和CPU消耗,还因为我需要保存列表的滚动位置,并再次滚动到用户留下片段的相同位置。这是可能的,但似乎应该存在一种更好的方式。
我试图将视图“保存”在片段上的一个私有字段中,并在已经存在的情况下重新使用它。
private View view = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.fragment_list, container, false);
//...
}
return view;
}
有没有其他更优雅的方式来避免重新膨胀布局?
我试过这样,它对我有用。
ViewModelnavGraphViewModels(实时导航范围)
- 在视图模型中存储任何以恢复状态
// fragment.kt
private val vm by navGraphViewModels<VM>(R.id.nav_graph) { vmFactory }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Restore state
vm.state?.let {
(recycler.layoutManager as GridLayoutManager).onRestoreInstanceState(it)
}
}
override fun onPause() {
super.onPause()
// Store state
vm.state = (recycler.layoutManager as GridLayoutManager).onSaveInstanceState()
}
// vm.kt
var state:Parcelable? = null
通过下面的实现,您可以获得片段的持久视图
基本片段
open class BaseFragment : Fragment(){
var hasInitializedRootView = false
private var rootView: View? = null
fun getPersistentView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?, layout: Int): View? {
if (rootView == null) {
// Inflate the layout for this fragment
rootView = inflater?.inflate(layout,container,false)
} else {
// Do not inflate the layout again.
// The returned View of onCreateView will be added into the fragment.
// However it is not allowed to be added twice even if the parent is same.
// So we must remove rootView from the existing parent view group
// (it will be added back).
(rootView?.getParent() as? ViewGroup)?.removeView(rootView)
}
return rootView
}
}
主片段
class MainFragment : BaseFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return getPersistentView(inflater, container, savedInstanceState, R.layout.content_main)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (!hasInitializedRootView) {
hasInitializedRootView = true
setListeners()
loadViews()
}
}
}
来源
google的Ian Lake回答我,我们可以将视图存储在变量中,而不是膨胀新的布局,只需在onCreateView()
上返回预存储视图的实例
资料来源:https://twitter.com/ianhlake/status/1103522856535638016
Leakcanary可能会将其显示为泄漏,但其为假阳性。。
本文向大家介绍vue 组件销毁并重置的实现,包括了vue 组件销毁并重置的实现的使用技巧和注意事项,需要的朋友参考一下 方法1 当数据变更后,通过watch 监听,先去销毁当前的组件,然后再重现渲染。使用 v-if 可以解决这个问题 方法2 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。
我有X、A、B片段,我使用导航架构组件在它们之间导航。 片段A、B特异性,但片段X可以是任何(C、D、...); 底部导航中的片段A和B及其“导航图标”始终在屏幕上,这意味着用户可以随时从任何片段(包括A和B)转到A或B: <代码>X- <代码>X- <代码>A- <代码>A-
我已经在我的项目中添加了一个导航抽屉活动,并尝试将项目作为片段添加。这就是我在主要活动中所做的。 默认片段是Home,它工作正常,正如预期的那样,但其他片段与Home片段重叠。(HomeFragment是唯一工作正常的)。我在每个片段类中都做过这样的事情: 我看不出错误在哪里。一切看起来都很好,但所有其他片段都显示在HomeFragment上。
vue3 接口pending 的时候,切换路由,理论当前实例会被销毁,autoUpdate 变量 和 visible 变量都不存在了,但是打印出来仍然存在。导致离开页面了,定时器还在执行。 关键点在,路由已经切换了 if (autoUpdateCheck.value && visibility.value === 'visible') 这个条件依然成立,导致定时器执行 1.组件实例为什么没有销毁
本文向大家介绍Android组件创建DrawerLayout导航,包括了Android组件创建DrawerLayout导航的使用技巧和注意事项,需要的朋友参考一下 概述 本篇博客是对developer.android.com/上的Training课程的简单翻译,若是觉得翻译出来的理解有困难,请点击下方链接查看原文! 关于DrawerLayout的Training:http://developer.
java.lang.runtimeException:无法启动活动ComponentInfo{com.farmbuy/com.farmbuy.farmer.farmersactivity}:Android.view.farmersactivity:二进制XML文件行#49:二进制XML文件行#49:在Android.app.activitythread.performLaunchActivity(