Я использую компонент Навигация в приложении Single Activity для навигации, но у меня странное поведение с одним фрагментом.Это просто объяснить с помощью изображений.
У меня есть фрагмент с ViewPager.ViewPager содержит еще два фрагмента, поэтому кажется:
Bird - первый фрагмент, Тест -второй.Нижний элемент - Нижняя навигация , это , а не часть фрагмента.Фрагмент находится между панель инструментов и Нижняя навигация .
Этот фрагмент, содержащий ViewPager, не является начальным фрагментом, он находится где-то посередине стека.
Итак, когда пользователь нажимает на нижний пункт меню, запускается этот код навигации (от Основная активность ):
bottom_navigation.apply {
itemIconTintList = null
setOnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.about_bottom -> {
findNavController(R.id.host).navigate(R.id.toAboutUs)
}
R.id.error_bottom -> {
findNavController(R.id.host).navigate(R.id.toMessage)
}
}
true
}
}
, где toMessage
/ toAboutUs
являются глобальными точками другого фрагмента.
Так в чем проблема.Когда пользователь нажимает на нижний пункт меню, все работает хорошо.Но когда он нажал «назад», контент от фрагментов пропал.Это просто увидеть:
Я даже не могу предложить причину, если это.Я знаю, что «основной» фрагмент и фрагменты на ViewPager не воссоздают, так почему они теряют контент?
Я нигде не переопределяю поведение кнопки возврата.Я просто использую app:defaultNavHost="true"
фрагмента хоста.
Как транспортируются данные: Когда пользователь нажимает кнопку, чтобы открыть Fragment с ViewPager, данные загружаются из DB и сохраняются только в ViewModelтогда пользователь будет перенесен в этот фрагмент.Когда оба дочерних фрагмента созданы, они загружают данные из ViewModel.И у меня нет места для кода, где я очищаю ViewModel, поэтому, когда пользователь нажимает назад, это на 100%, моя ViewModel содержит что-то.Но это не отображается.
UPD: Потратив некоторое время, я понимаю, что два «дочерних» фрагмента восстанавливаются не при возвращении назад, а в основном фрагменте.Я думаю, что проблема в этом, но все еще не понимаю, где именно.
Мне нужна ваша помощь, чтобы понять, что происходит.
Upd: предоставить некоторый код создания фрагментов. BaseCompatFragment расширяет Фрагмент
MainFragment (контейнер для двух других фрагментов):
class QuestionFragment : BaseCompatFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_question, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
pager.adapter = QuestionViewPagerAdapter(fragmentManager!!)
activity?.toolbar_title?.text = getString(R.string.title_question,1)
layout_tab.apply {
setupWithViewPager(pager)
tabIconTint = null
getTabAt(0)?.setIcon(R.drawable.ic_type_bird)
getTabAt(1)?.setIcon(R.drawable.ic_hints)
}
}
}
QuestionViewPagerAdapter
class QuestionViewPagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
override fun getItem(position: Int): BaseCompatFragment {
when (position) {
0 -> return HintsFragment()
1 -> return BaseInfoFragment()
}
return HintsFragment()
}
override fun getCount(): Int {
return 2
}
}
HintsFragment (птица)
class HintsFragment : BaseCompatFragment(), HintsFragmentContract.View {
@Inject
lateinit var presenter: HintsFragmentPresenter
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_hints, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
LibApp.get().injector.inject(this)
presenter.attach(this)
val animalWithHints =
ViewModelProviders.of(activity!!).get(AnimalViewModel::class.java).getData().value
val adapter = HintsAdapter(callback = { id ->
//Some code will be here soon
})
//Do smth with content
adapter.hintsList = animalWithHints?.animal?.hints?.split("///") as ArrayList<String>
adapter.hintsStorage = animalWithHints.hints?.get(0) ?: Hints()
recycler_hints.layoutManager = verticalManager(context)
recycler_hints.adapter = adapter
}
}
BaseInfoFragment (тест)
class BaseInfoFragment : BaseCompatFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_base_info, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
val animalWithHints =
ViewModelProviders.of(activity!!).get(AnimalViewModel::class.java).getData().value
//A lot of logic to hide/show content, don't think it can be intresting
val isBaseInfoOpen = animalWithHints?.hints?.get(0)?.baseInfoOpened == 1
setBlockLayoutState(!isBaseInfoOpen)
if (isBaseInfoOpen) {
openContent(animalWithHints)
} else {
text_base_info.text = getString(R.string.base_info_price, 100)
btn_base_info_positive.setOnClickListener {
if (btn_base_info_negative.visibility == View.GONE) {
btn_base_info_negative.visibility = View.VISIBLE
text_base_info.text = getString(R.string.default_doubts)
} else {
openContent(animalWithHints)
}
}
btn_base_info_negative.setOnClickListener {
it.visibility = View.GONE
text_base_info.text = getString(R.string.base_info_price, 100)
}
}
}
private fun getRareIcon(rare: Int, context: Context): Drawable {
return when (rare) {
1 -> ContextCompat.getDrawable(context, R.drawable.ic_rare_fine)!!
2 -> ContextCompat.getDrawable(context, R.drawable.ic_rare_medium)!!
3 -> ContextCompat.getDrawable(context, R.drawable.ic_rare_bad)!!
else -> ContextCompat.getDrawable(context, R.drawable.ic_warning)!!
}
}
private fun getRareText(rare: Int): String {
return when (rare) {
1 -> getString(R.string.base_info_rare_1)
2 -> getString(R.string.base_info_rare_2)
3 -> getString(R.string.base_info_rare_3)
else -> getString(R.string.base_info_rare_4)
}
}
private fun setBlockLayoutState(state: Boolean) {
base_info_closer.visibility = when {
state -> View.VISIBLE
else -> View.GONE
}
base_info_content.visibility = when {
state -> View.GONE
else -> View.VISIBLE
}
}
private fun openContent(animalWithHints: AnimalWithHints?) {
(img_closed_base_info.drawable as Animatable).start()
rare_img.setImageDrawable(getRareIcon(animalWithHints?.animal?.rare ?: 0, activity!!))
rare_text.text = getRareText(animalWithHints?.animal?.rare ?: 0)
setBlockLayoutState(false)
}
}