Параметры Меню исчезает из фрагмента при изменении ориентации - PullRequest
0 голосов
/ 11 июля 2020

Значки в меню параметров работают нормально, но при изменении ориентации путем поворота экрана значки исчезают.

class SingleRecipeFragment : Fragment() {

    private lateinit var viewModel: SingleRecipeViewModel
    private lateinit var viewModelFactory: SingleRecipeViewModelFactory

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val binding: FragmentSingleRecipeBinding = DataBindingUtil.inflate(inflater,
            R.layout.fragment_single_recipe, container, false)
        val args =
            SingleRecipeFragmentArgs.fromBundle(
                requireArguments()
            )

        val application = requireNotNull(this.activity).application

        viewModelFactory =
            SingleRecipeViewModelFactory(
                args.recipeIndex, application
            )
        viewModel = ViewModelProvider(this,viewModelFactory)
            .get(SingleRecipeViewModel::class.java)

        binding.singleRecipeViewModel = viewModel
        binding.lifecycleOwner = this

        viewModel.curRecipe.observe(viewLifecycleOwner, Observer {
            (requireActivity() as MainActivity).toolbar.title = it?.title
        })

        //Toast.makeText(context, "Recipe Number: ${args.recipeIndex}",Toast.LENGTH_LONG).show()
        setHasOptionsMenu(true)
        return binding.root
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
        inflater.inflate(R.menu.single_recipe_menu, menu)

        viewModel.curRecipe.observe(viewLifecycleOwner, Observer {
            val favIconDrawable: Int = if (it!!.favorite) R.drawable.ic_baseline_star_filled_24
            else R.drawable.ic_baseline_star_border_24
            menu.findItem(R.id.favorite).setIcon(favIconDrawable)
        })
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.share -> viewModel.shareSuccess(this.requireActivity())
            R.id.favorite -> viewModel.toggleFavorite()
        }
        return super.onOptionsItemSelected(item)
    }
}

Вот макет меню:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/share"
        android:enabled="true"
        android:icon="@drawable/ic_baseline_share_24"
        android:title="Share"
        android:visible="true"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/favorite"
        android:enabled="true"
        android:icon="@drawable/ic_baseline_star_border_24"
        android:title="Share"
        android:visible="true"
        app:showAsAction="ifRoom" />
</menu>

Этот фрагмент запускается из другого фрагмента с помощью NavigationUI, который передает значение recipeID. Я пробовал использовать setHasOptionsMenu (true) в onResume этого фрагмента, но это не помогло. Есть идеи, почему optionsMenu не сохраняется?

1 Ответ

0 голосов
/ 11 июля 2020

Похоже, что использование setSupportActionBar(toolbar) в методе onCreate() MainActivity решает проблему с непостоянством optionsMenu. Однако это нарушает метод, который я использовал для отображения заголовка на фрагменте windows.

Панель инструментов принадлежит Activity, а не фрагменту. Поэтому, когда представление воссоздается после изменения ориентации, на панели инструментов устанавливается заголовок приложения. Этого не происходит, когда фрагмент загружается впервые, так как заголовок был установлен onCreate() фрагмента. Решением было переместить настраиваемые заголовки в onResume() фрагмента, чтобы они сбрасывались каждый раз, когда представление отображается на экране.

Я устанавливаю заголовок во фрагменте, как это , потому что если я позволю контроллеру навигации делать это с помощью меток в навигации. xml Я получаю странное поведение, когда фрагмент загружается, когда настраиваемый макет панели инструментов заменяется новым типом заголовка фрагмента, мигает справа.

Таким образом, сводный код для этого решения:

Фрагмент:

class SingleRecipeFragment : Fragment() {

    override fun onCreateView(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onResume() {
        super.onResume()
        /** This will reset your title every time the fragment is redrawn **/
        (requireActivity() as MainActivity).toolbar.title = "Some Custom Title"
    }

    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        super.onCreateOptionsMenu(menu, inflater)
        inflater.inflate(R.menu.single_recipe_menu, menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.share -> someMethodYouWantToRun()
            R.id.favorite -> someOtherMethod()
        }
        return super.onOptionsItemSelected(item)
    }
}

В onCreate() вашего Activity, вызовите:

setSupportActionBar(toolbar)

А вот файл ресурсов макета меню, расширяемый для меню параметров (без изменений по сравнению с тем, что в вопросе):

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/share"
        android:enabled="true"
        android:icon="@drawable/ic_baseline_share_24"
        android:title="Share"
        android:visible="true"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/favorite"
        android:enabled="true"
        android:icon="@drawable/ic_baseline_star_border_24"
        android:title="Share"
        android:visible="true"
        app:showAsAction="ifRoom" />
</menu>
...