有人告诉我以下,但我有点困惑。
请问,您能确认或提出异议吗?
(该片段不通过 setRetainInstance()
目前,在 Fragment 中初始化视图是一种常见的做法,如下所示:
private lateinit var myTextView: TextView
fun onViewCreated(view: View, bundle: Bundle) {
...
myTextView = view.findViewById(R.id.myTextViewId)
...
}
Run Code Online (Sandbox Code Playgroud)
然后我们永远不会取消这个属性。虽然这是一种常见的做法,但它会导致内存泄漏。
背景:
比方说,FragmentA有一个对它的 childView 的引用View,作为一个实例字段。FragmentManager 使用特定的 FragmentTransaction 执行从片段 A 到 B 的导航。根据事务的类型,管理器可能想要杀死View唯一但仍然保留的实例FragmentA(请参阅下面的生命周期部分,其中说“片段从后堆栈返回到布局”)。当用户从FragmentBto返回时FragmentA,前一个实例 的FragmentA将被带到前面,但View会创建一个新实例。
问题是,如果我们在 lateinit 属性中保留视图的实例并且从不清除对它的引用,则视图无法完全销毁,从而导致内存泄漏。
我的适配器的 nav_graph 中定义的呼叫导航操作有问题。
我试图调用Navigation.findNavController(v).navigate(id_myaction) 的bind函数ViewHolder但它不起作用,我得到了
错误:“查看 androidx.constraintlayout.widget.ConstraintLayout{96d8d23 VE..C.. ...P.. 0,471-1080,628} 没有设置 NavController”
这是我的行动:
<fragment
android:id="@+id/eventListFragment"
android:name="EventListFragment"
android:label="fragment_event_list"
tools:layout="@layout/fragment_event_list" >
<action
android:id="@+id/action_eventListFragment_to_startEventFragment"
app:destination="@id/startEventFragment" />
</fragment>
Run Code Online (Sandbox Code Playgroud)
这是我的适配器:
class EventListAdapter(val findNavController: NavController) : RecyclerView.Adapter<EventListAdapter.ViewHolder>() {
private lateinit var eventList:List<Event>
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EventListAdapter.ViewHolder {
val binding: EventListItemBinding = DataBindingUtil.inflate(LayoutInflater.from(parent.context), R.layout.event_list_item, parent, false)
return ViewHolder(binding,findNavController)
}
override fun onBindViewHolder(holder: EventListAdapter.ViewHolder, position: Int) {
holder.bind(eventList[position])
}
override fun getItemCount(): Int {
return if(::eventList.isInitialized) eventList.size else 0
} …Run Code Online (Sandbox Code Playgroud)