当前位置: 首页 > 知识库问答 >
问题:

Jetpack Android导航组件销毁/重建的碎片

宰鸿博
2023-03-14

我正在尝试在我现有的应用程序中使用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;
}

有没有其他更优雅的方式来避免重新膨胀布局?

共有3个答案

公良扬
2023-03-14

我试过这样,它对我有用。

  • InitViewModelnavGraphViewModels(实时导航范围)
  • 在视图模型中存储任何以恢复状态
// 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

太叔经赋
2023-03-14

通过下面的实现,您可以获得片段的持久视图

基本片段

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()
        }
    }
}

来源

党祖鹤
2023-03-14

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(