英文:
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) -> {
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> 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();
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论