[英]How to pause a fragment in ViewPager + TabLayout when a different tab is selected?
Right now I have a tablayout with a ViewPager + adapter below it.现在我有一个标签布局,下面有一个 ViewPager + 适配器。 I want to pause a fragment when a different tab is selected (not destroy/pop it, just pause it) and resume it when the fragment's tab is selected.我想在选择不同的选项卡时暂停片段(不是销毁/弹出它,只是暂停它)并在选择片段的选项卡时恢复它。
public class PagerFragment extends Fragment {
ViewPagerAdapter pagerAdapter;
ViewPager pager;
TabLayout tabLayout;
int position;
public PagerFragment() {
super();
}
public void setPosition(int position) {
this.position = position;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onStop() {
super.onStop();
}
@Override
public void onPause() {
super.onPause();
pagerAdapter.clear();
pagerAdapter.notifyDataSetChanged();
}
@Override
public void onStart() {
super.onStart();
}
@Override
public void onResume() {
super.onResume();
if (!isAdded()) {
pagerAdapter.instantiateItem(pager, position);
}
}
@SuppressLint("InflateParams")
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.fragment_pager, null);
pagerAdapter = new ViewPagerAdapter(getChildFragmentManager());
setPosition(position);
pagerAdapter.setDevicesList(devicesList);
pager = root.findViewById(R.id.pager);
pager.setAdapter(pagerAdapter);
tabLayout = root.findViewById(R.id.tab_layout);
for (int i = 0; i < devicesList.size(); i++) {
tabLayout.addTab(tabLayout.newTab().setText(String.valueOf(devicesList.get(i).getName())));
}
TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
pager.setCurrentItem(position);
tabLayout.setupWithViewPager(pager);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
int pos = tab.getPosition();
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(pager));
return root;
}
}
public class ViewPagerAdapter extends FragmentPagerAdapter {
ArrayList<ConnectedBluetoothDevice> devicesList;
ArrayList<DataViewFragment> dataViewFragments;
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
/**
* Initializes the adaptor with the device list and the list of data fragments.
* @param devicesList List of devices to be displayed in their own data fragment.
*/
public void setDevicesList(ArrayList<ConnectedBluetoothDevice> devicesList) {
this.devicesList = devicesList;
dataViewFragments = new ArrayList<>();
for (int i = 0; i < devicesList.size(); i++) {
dataViewFragments.add(new DataViewFragment(devicesList.get(i)));
}
}
/**
* GetItem
* @param position position of item in the viewPager list to be returned
* @return fragment to view
*/
@NonNull
public Fragment getItem(int position) {
if (dataViewFragments != null && position < dataViewFragments.size()) {
return dataViewFragments.get(position);
} else {
return new DataViewFragment(null);
}
}
@Override
public int getCount() {
return devicesList.size();
}
/**
* Updates the tabs in tabLayout while swiping pages
* @param position of the viewPage
* @return title of the tab
*/
public CharSequence getPageTitle(int position) {
super.getPageTitle(position);
return devicesList.get(position).getName();
}
public void clear() {
dataViewFragments.clear();
}
}
Some notes:一些注意事项:
setOffscreenPageLimit(0);
我听说setOffscreenPageLimit(0);
isn't the best practice so I want to avoid that situation (especially since I only need to pause the fragment but not destroy it)不是最佳实践,所以我想避免这种情况(特别是因为我只需要暂停片段而不破坏它) This depends on the version of ViewPager
you are using as it was added later.这取决于您使用的ViewPager
版本,因为它是稍后添加的。
Your are using a deprecated constructor您正在使用已弃用的构造函数
So as long as your using a recent version of Viewpager
you should use the non deprecated constructor:-因此,只要您使用最新版本的Viewpager
,您就应该使用不推荐使用的构造函数:-
public FragmentPagerAdapter(
@NonNull FragmentManager fm,
@FragmentPagerAdapter.Behavior int behavior
)
This constructor with the behaviour BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
此构造函数具有行为BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
then only the current Fragment is in the RESUMED state.那么只有当前片段在 RESUMED state 中。 All other fragments are capped at STARTED所有其他片段的上限为 STARTED
To get to the STARTED
lifecycle state from RESUMED
onPause
is called.为了从RESUMED
onPause
进入STARTED
生命周期 state 被调用。
so change所以改变
public ViewPagerAdapter(FragmentManager fm) {
super(fm);
}
to至
public ViewPagerAdapter(FragmentManager fm) {
super(fm, BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
}
This method is used to for calling functions to run only when the specified tab is selected.此方法用于仅在选择指定选项卡时调用函数才能运行。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// add your tab functions here
} else {
// do nothing
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.