选中的标签在返回应用程序后不显示在屏幕上。

huangapple go评论79阅读模式
英文:

Selected tab in TabLayout is not shown on screen after returning to app

问题

我正在使用 <code>ViewPager2</code> 与 <code>TabLayout</code> 以及 <code>TabLayoutMediator</code> 来显示一些片段。
当我离开应用程序(例如通过点击主页按钮)然后再次打开它时,<code>TabLayout</code> 会跳转到其他一些选项卡上。
正确的选项卡,即用户离开应用程序时所在的最后一个选项卡,仍然被选中,并且仍然显示了正确的片段。只是选项卡布局由于某种原因滚动到了与之无关的位置。

可能的问题是什么?

这是我的代码:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mViewModel = new ViewModelProvider(this).get(UserItemsViewModel.class);

    viewPager = view.findViewById(R.id.view_pager);
    tabLayout = view.findViewById(R.id.tab_layout);

    viewPager.setAdapter(new ItemListFragmentAdapter(requireActivity(), mType));
    tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager,
            (tab, position) -> {
                if (position == 0) {
                    tab.setText("All");
                } else {
                    tab.setText(((ItemListFragmentAdapter) viewPager.getAdapter()).getItemAt(position - 1).getName());
                }
            }
    );

    mViewModel.getFormatsLD().observe(getViewLifecycleOwner(), new Observer<List<FormatItem>>() {
        @Override
        public void onChanged(List<FormatItem> formatItems) {
            ItemListFragmentAdapter adapter = (ItemListFragmentAdapter) viewPager.getAdapter();
            if (adapter != null) {
                ((ItemListFragmentAdapter) viewPager.getAdapter()).setItems(formatItems);
                adapter.notifyDataSetChanged();
            }
        }
    });
}

@Override
public void onResume() {
    super.onResume();
    tabLayoutMediator.attach();
    viewPager.setCurrentItem(currentPage, false);
}

@Override
public void onPause() {
    super.onPause();
    currentPage = viewPager.getCurrentItem();
    tabLayoutMediator.detach();
}

<code>currentPage</code> 是托管 <code>ViewPager2</code> 和 <code>TabLayout</code> 的父片段中的字段,用于在片段暂停时保留用户所在的最后一个选项卡/页面。

您可以在下面的图片中看到离开应用程序前后的外观:

[![进入图片描述][1]][1]


[![进入图片描述][2]][2]

  [1]: https://i.stack.imgur.com/ubcs4.jpg
  [2]: https://i.stack.imgur.com/KUvKZ.jpg
英文:

I am using <code>ViewPager2</code> along with <code>TabLayout</code> and <code>TabLayoutMediator</code> to display some fragments.
I have a problem when I leave the app (for example by tapping the home button) and then open it again, the <code>TabLayout</code> jumps to some other tabs. The correct tab, i.e. the last one the user was on when he left the app, is still selected and the correct fragment is still shown. It's just the tabs layout that gets scrolled to an unrelated position for some reason.

What can be the problem?

This is my code:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mViewModel = new ViewModelProvider(this).get(UserItemsViewModel.class);

    viewPager = view.findViewById(R.id.view_pager);
    tabLayout = view.findViewById(R.id.tab_layout);

    viewPager.setAdapter(new ItemListFragmentAdapter(requireActivity(), mType));
    tabLayoutMediator = new TabLayoutMediator(tabLayout, viewPager,
            (tab, position) -&gt; {
                if (position == 0) {
                    tab.setText(&quot;All&quot;);
                } else {
                    tab.setText(((ItemListFragmentAdapter) viewPager.getAdapter()).getItemAt(position - 1).getName());
                }
            }
    );

    mViewModel.getFormatsLD().observe(getViewLifecycleOwner(), new Observer&lt;List&lt;FormatItem&gt;&gt;() {
        @Override
        public void onChanged(List&lt;FormatItem&gt; formatItems) {
            ItemListFragmentAdapter adapter = (ItemListFragmentAdapter) viewPager.getAdapter();
            if (adapter != null) {
                ((ItemListFragmentAdapter) viewPager.getAdapter()).setItems(formatItems);
                adapter.notifyDataSetChanged();

            }
        }
    });
}

@Override
public void onResume() {
    super.onResume();
    tabLayoutMediator.attach();
    viewPager.setCurrentItem(currentPage, false);


}

@Override
public void onPause() {
    super.onPause();
    currentPage = viewPager.getCurrentItem();
    tabLayoutMediator.detach();
}

<code>currentPage</code> is a field in the parent fragment which hosts the <code>ViewPager2</code> and <code>TabLayout</code> which is used to retain the last tab/page the user was on when the fragment got paused.

You can see in these photos below how it looks before leaving the app and after returning to it:

选中的标签在返回应用程序后不显示在屏幕上。

选中的标签在返回应用程序后不显示在屏幕上。

答案1

得分: 1

.detach().attach()onPause中移除,并将.attach()移到onCreateView()中:

@Override
public void onResume() {
    super.onResume();
    viewPager.setCurrentItem(currentPage, false);
}

@Override
public void onPause() {
    super.onPause();
    currentPage = viewPager.getCurrentItem();
}

这是不必要的,因为垃圾回收会自动执行,但考虑到最佳实践:

@Override
public void onDestroy() {
    super.onDestroy();
    tabLayoutMediator.detach();
}
英文:

Remove .detach() and .attach() from on pause and move .attach() to onCreateView()

@Override
public void onResume() {
    super.onResume();
    viewPager.setCurrentItem(currentPage, false);
}

@Override
public void onPause() {
    super.onPause();
    currentPage = viewPager.getCurrentItem();
}

it's not necessary because garbage collection automatedly does so, but itconsidered as best practice

@Override
public void onDestroy() {
    super.onDestroy();
    tabLayoutMediator.detach();
}

huangapple
  • 本文由 发表于 2020年9月13日 22:34:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/63871949.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定