Android fragments 如何销毁使用fragmentstateadapter(viewpager2)创建的片段
在ViewPager2位于片段中的静态(3页)ViewPager2设置中,我在FragmentStateAdapter子体中创建了3个片段。我甚至在该子体的一个表(Android fragments 如何销毁使用fragmentstateadapter(viewpager2)创建的片段,android-fragments,kotlin,android-room,android-livedata,android-viewpager2,Android Fragments,Kotlin,Android Room,Android Livedata,Android Viewpager2,在ViewPager2位于片段中的静态(3页)ViewPager2设置中,我在FragmentStateAdapter子体中创建了3个片段。我甚至在该子体的一个表(MutableList=Vector())中收集了片段,以供以后参考。offscreenPageLimit设置为3,因此片段不会消失,只会恢复并暂停 一个片段是地图,一个片段是带有多个livedata引用的表设置(基于房间),第三个片段是图片页 当离开这个ViewPager2片段并回收房间数据库(刷新内容)时,我的应用程序崩溃了。。。
MutableList=Vector()
)中收集了片段,以供以后参考。offscreenPageLimit
设置为3
,因此片段不会消失,只会恢复并暂停
一个片段是地图,一个片段是带有多个livedata引用的表设置(基于房间),第三个片段是图片页
当离开这个ViewPager2片段并回收房间数据库(刷新内容)时,我的应用程序崩溃了。。。我突然想到,在FragmentStateAdapter子代中创建的三个片段没有被销毁(当然?)(片段无法处理空数据库),因为FragmentStateAdapter无法杀死这些片段。当然我可以在他们的后代中杀死他们,但是没有简单的方法来处理这些死亡吗
下面的大部分代码都是基于模板的,因此有些代码可能是不必要的
代码摘录:
AddStationFragment:
class AddStationFragment : Fragment() {
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
private var listener: OnFragmentInteractionListener? = null
private val TAG by lazy { this::class.java.simpleName }
private lateinit var adRequest: AdRequest
private lateinit var binding: FragmentAddStationBinding
private lateinit var viewModel: AddStationViewModel
var fragments: MutableList<Fragment> = Vector<Fragment>()
lateinit var addStationFragmentStateAdapter: AddStationFragmentStateAdapter
override fun onCreate(savedInstanceState: Bundle?) {
Log.i(TAG,"fra: onCreate()")
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onResume() {
Log.i(TAG,"fra: onResume()")
super.onResume()
activity?.let {activity->
activity.fab?.let { fab ->
fab.hide()
fab.setImageDrawable(resources.getDrawable(R.drawable.ic_baseline_check_24, context?.theme))
fab.clearAnimation()
//fab.isEnabled = false
fab.setOnClickListener { view ->
Log.i(TAG,"fab.clicked !")
}
//fab.show()
}
(activity as MainActivity).setOptionsMenu(OptionsMenuSet.ADDSTATION)
activity.bottom_navigation.visibility=View.GONE
listener?.registerFragment(this)
}
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
Log.i(TAG,"fra: onViewCreated")
val tabtext = arrayOf(
"Location",
"Address",
"Enterprise")
val iconresource = arrayOf(
R.drawable.ic_add_location_black_24dp,
R.drawable.ic_info_outline_black_24dp,
R.drawable.ic_baseline_business_24)
TabLayoutMediator(
binding.addStationTabLayout,
binding.addStationViewPager2,
TabLayoutMediator.TabConfigurationStrategy { tab: TabLayout.Tab, position: Int ->
tab.text = tabtext[position]
tab.setIcon(iconresource[position])
tab.icon?.let { icon ->
DrawableCompat.setTint(
icon,
ContextCompat.getColor(activity as Context, R.color.cardBG_lightred))
}
/*tab.icon?.setColorFilter(
ContextCompat.getColor(activity as Context, R.color.cardBG_lightred),
PorterDuff.Mode.SRC_IN)*/ //Deprecated
}
).attach()
//super.onViewCreated(view, savedInstanceState)
}
override fun onDestroy() {
Log.i(TAG,"fra: onDestroy()")
Log.i(TAG,"fra: Childfragment size: ${childFragmentManager.fragments.size}")
super.onDestroy()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
Log.i(TAG,"fra: onCreateView()")
binding = FragmentAddStationBinding.inflate(inflater, container, false)
context?:return binding.root
adRequest = AdRequest.Builder().build()
binding.addStationAdView.loadAd(adRequest)
addStationFragmentStateAdapter = AddStationFragmentStateAdapter(
activity?:return binding.root,fragments)
binding.addStationViewPager2.offscreenPageLimit = 3
binding.addStationViewPager2.adapter = addStationFragmentStateAdapter
val factory = InjectorUtils.provideAddStationViewModelFactory(context?:return binding.root)
viewModel = ViewModelProvider(this, factory).get(AddStationViewModel::class.java)
viewModel.liveNewStationForUser.observe(viewLifecycleOwner, Observer { station ->
Log.i(TAG,"onCreateView liveNewStationForUser station = $station")
})
AddStationRepository.createTemplate("")
return binding.root
}
// TODO: Rename method, update argument and hook method into UI event
fun onButtonPressed(uri: Uri) {
listener?.onFragmentInteraction(uri)
}
override fun onAttach(context: Context) {
Log.i(TAG,"fra: onAttach()")
super.onAttach(context)
if (context is OnFragmentInteractionListener) {
listener = context
} else {
throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
}
}
override fun onPause() {
Log.i(TAG,"fra: onPause()")
super.onPause()
}
override fun onDetach() {
Log.i(TAG,"fra: onDetach()")
super.onDetach()
listener = null
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
*
*
* See the Android Training lesson [Communicating with Other Fragments]
* (http://developer.android.com/training/basics/fragments/communicating.html)
* for more information.
*/
interface OnFragmentInteractionListener {
// TODO: Update argument type and name
fun onFragmentInteraction(uri: Uri)
fun registerFragment(fragment: Fragment)
fun unregisterFragment(fragment: Fragment)
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* @param param1 Parameter 1.
* @param param2 Parameter 2.
* @return A new instance of fragment AddStationFragment.
*/
// TODO: Rename and change types and number of parameters
@JvmStatic
fun newInstance(param1: String, param2: String) =
AddStationFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
}
class AddStationFragment:Fragment(){
//TODO:重命名和更改参数类型
私有变量param1:字符串?=null
私有变量param2:字符串?=null
私有变量侦听器:OnFragmentInteractionListener?=null
惰性{this::class.java.simpleName}的私有val标记
私有lateinit var adRequest:adRequest
私有lateinit变量绑定:FragmentAddStationBinding
私有lateinit变量viewModel:AddStationViewModel
变量片段:MutableList=Vector()
lateinit变量addStationFragmentStateAdapter:addStationFragmentStateAdapter
重写创建时的乐趣(savedInstanceState:Bundle?){
Log.i(标记“fra:onCreate()”)
super.onCreate(savedInstanceState)
争论?让我们{
param1=it.getString(ARG_param1)
param2=it.getString(ARG_param2)
}
}
重写onResume(){
Log.i(标记“fra:onResume()”)
super.onResume()
活动?.let{activity->
activity.fab?.let{fab->
制作隐藏
工厂setImageDrawable(resources.getDrawable(R.drawable.ic\u baseline\u check\u 24,context?.theme))
制作clearAnimation()
//fab.isEnabled=false
fab.setOnClickListener{view->
Log.i(标记“fab.clicked!”)
}
//制作秀
}
(活动作为主活动)。设置选项菜单(选项菜单Uset.ADDSTATION)
activity.bottom\u navigation.visibility=View.GONE
侦听器?.registerFragment(此)
}
}
覆盖已创建的视图(视图:视图,保存状态:捆绑?){
Log.i(标记“fra:onViewCreated”)
val tabtext=arrayOf(
“地点”,
“地址”,
“企业”)
val iconresource=arrayOf(
R.drawable.ic\U添加位置\U黑色\U 24dp,
R.drawable.ic_信息_轮廓_黑色_24dp,
R.drawable.ic_基线_业务_24)
调停人(
binding.addStationTableOut,
binding.addStationViewPager2,
TabLayoutMediator.TabConfigurationStrategy{tab:TabLayout.tab,位置:Int->
tab.text=tabtext[位置]
选项卡.设置图标(iconresource[位置])
tab.icon?.let{icon->
DrawableCompat.setTint(
偶像
ContextCompat.getColor(活动作为上下文,R.color.cardBG_浅红色))
}
/*选项卡.图标?.setColorFilter(
ContextCompat.getColor(活动作为上下文,R.color.cardBG_浅红色),
PorterDuff.Mode.SRC_IN)*///已弃用
}
)附(
//super.onViewCreated(视图,savedInstanceState)
}
重写onDestroy(){
Log.i(标记“fra:onDestroy()”)
Log.i(标记,“fra:childfragmentsize:${childFragmentManager.fragments.size}”)
super.ondestory()
}
覆盖创建视图(
充气器:布局充气器,容器:视图组?,
savedInstanceState:捆绑?
):查看{
//为该碎片膨胀布局
Log.i(标记“fra:onCreateView()”)
绑定=碎片添加站绑定。充气(充气机、容器、假)
上下文?:返回binding.root
adRequest=adRequest.Builder().build()
binding.addStationAdView.loadAd(adRequest)
addStationFragmentStateAdapter=addStationFragmentStateAdapter(
活动?:返回绑定。根,片段)
binding.addStationViewPager2.offscreenPageLimit=3
binding.addStationViewPager2.adapter=addStationFragmentStateAdapter
val factory=InjectorUtils.providedStationViewModelFactory(上下文?:返回binding.root)
viewModel=ViewModelProvider(this,factory).get(AddStationViewModel::class.java)
viewModel.liveNewStationForUser.observe(viewLifecycleOwner,Observer{station->
Log.i(标记“onCreateView liveNewStationForUser station=$station”)
})
AddStationRepository.createTemplate(“”)
返回binding.root
}
//TODO:重命名方法、更新参数并将方法挂接到UI事件中
按下按钮(uri:uri){
侦听器?.onFragmentInteraction(uri)
}
重写转速表(上下文:上下文){
Log.i(标记“fra:onAttach()”)
super.onAttach(上下文)
if(上下文是OnFragmentInteractionListener){
侦听器=上下文
}否则{
抛出运行时异常(context.toString()+“必须实现OnFragmentInteractionListener”)
}
}
覆盖暂停(){
Log.i(标记“fra:onPause()”)
super.onPause()
}
覆盖连接(){
Log.i(标记“fra:onDetach()”)
super.onDetach()
侦听器=null
}
/**
*此接口必须由包含以下内容的活动实现
*片段,以允许通信此片段中的交互
*该活动以及其中可能包含的其他片段
*活动。
*
*
*请参阅Android培训课程[与其他片段交流]
* (http://develo
class AddStationFragmentStateAdapter(
fragmentActivity: FragmentActivity,
private val fragmentList: MutableList<Fragment>
) :
FragmentStateAdapter(fragmentActivity) {
private val TAG by lazy {this::class.java.simpleName}
override fun createFragment(position: Int): Fragment {
Log.i(TAG, "createFragment position = $position")
val fragment: Fragment = when (position) {
0 -> FragmentAddStationMap()
1 -> FragmentAddStationInfo()
else -> FragmentAddStationEnterprise()
}
if (fragmentList.size <= position)
fragmentList.add(fragment)
else
fragmentList[position] = fragment
Log.i(TAG, "fra: fragmentList.size = ${fragmentList.size}")
return fragment
}
override fun getItemCount(): Int {
Log.i(TAG,"fra: fragmentListSize = ${fragmentList.size}")
return 3
}
}
class AddStationFragmentStateAdapter(
fragmentActivity: FragmentActivity,
public var fragmentList: MutableList<Fragment> //changed to public
) :
FragmentStateAdapter(fragmentActivity) {
private val TAG by lazy {this::class.java.simpleName}
...
override fun onDestroy() {
Log.i(TAG,"fra: onDestroy()")
Log.i(TAG,"fra: Childfragment size: ${childFragmentManager.fragments.size}")
Log.i(TAG,"fra: addStationFragmentStateAdapter.fragmentList.size = ${addStationFragmentStateAdapter.fragmentList.size}")
addStationFragmentStateAdapter.fragmentList.forEach { fragment:Fragment ->
fragment.parentFragmentManager.beginTransaction().remove(fragment).commit()
}
super.onDestroy()
}
class MainPagerAdapter(fragment: MyParentFragment) : FragmentStateAdapter(fragment) {}