В состоянии c (3 страницы) в настройке ViewPager2, где ViewPager2 находится во фрагменте, я создал 3 фрагмента в потомке FragmentStateAdapter. Я даже собрал фрагменты в таблице (MutableList<Fragment> = Vector<Fragment>()
) в этом потомке для дальнейшего использования. offscreenPageLimit
установлен на 3
, поэтому фрагменты не будут d ie, а будут только возобновлены и приостановлены.
Один фрагмент представляет собой карту, один фрагмент представляет собой таблицу настроек с несколькими ссылками на жилые данные ( на основе помещения), третьим будет страница с изображением.
При выходе из этого фрагмента ViewPager2 и повторной обработке базы данных помещения (обновление содержимого) мое приложение не работает ... мне пришло в голову, что три фрагмента, созданные в Потомок FragmentStateAdapter не был уничтожен (конечно?) (Обнуленная база данных не может быть обработана фрагментом), потому что 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)
}
}
}
}
AddStationFragmentStateAdapter: (потомок FragmentStateAdapter)
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
}
}
Итак ... что вы должны сделать? в onDestroy()
для AddStationFragment
я проверил childFragmentManager
, но там нет никаких фрагментов (как и следовало ожидать, поскольку я предоставил fragmentActivity
в вызове FragmentStateAdapter
(в FragmentStateAdapter
потомок AddStationFragmentStateAdapter
), где они сидят и кто (и как) должен (я) уничтожить их наилучшим образом?
RG