将ViewPager与片段一起使用时,在选项卡之间移动时不会调用onPause(),onResume()方法。当我们被显示或被隐藏时,我们是否有任何方法可以在片段中找到答案?
不幸的是我在onResume(),onPause()中有逻辑,比如注册位置服务,在切换标签时永远不会停止,因为在退出整个应用程序之前,onPause()永远不会被调用。
由于
答案 0 :(得分:17)
ViewPager附带OnPageChangeListener
界面。通过为先前和当前显示的页面设置一些标志,您可以模拟此行为。
答案 1 :(得分:10)
考虑到以前的解决方案不是很清楚,这是我解决它的方式,感谢Phix的提示:
在OnPageChange()回调中:
Fragment old_fragment = getActiveFragment(old_position);
Fragment new_fragment = getActiveFragment(new_position);
old_f.setUserVisibleHint(false);
old_f.onPause();
new_f.setUserVisibleHint(true);
new_f.onResume();
然后在onResume():
if (getUserVisibleHint())
/* resume code */
并在onPause()中:
if (!getUserVisibleHint())
/* pause code */
这是getActiveFragment代码,避免搜索它:
return fragmentManager.findFragmentByTag("android:switcher:" + viewPagerId + ":" + position);
注意:片段有一个isVisible()方法,但它似乎不是很一致,因此使用了UserVisibleHint。
编辑:用私有标志替换UserVisibleHint。工作得更好!
答案 2 :(得分:6)
如果您正在使用Android支持库(第11版),则可以使用getUserVisibleHint()或覆盖setUserVisibleHint()来捕获可见和隐藏的更改。看这个post。
@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
super.setUserVisibleHint(isVisibleToUser);
if (isVisibleToUser) {
// do something when visible.
}
}

答案 3 :(得分:2)
解决方案1:
在SparseArray
'适配器中定义ViewPagers
,如下所示。在这个数组中,我们将保存片段的实例。
SparseArray<Fragment> registeredFragments = new SparseArray<>();
Override
适配器的instantiateItem
方法。
@Override
public Object instantiateItem(ViewGroup container, int position) {
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
Override
destroyItem
ViewPagers
方法
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
定义一种新方法来获取ViewPager
Fragments
个实例。
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
现在,您可以使用ViewPager's
OnPageChangeListener
实现逻辑。
这是一个关于如何实现viewpager的onPageChangeListener
:
定义一个整数以保持当前位置:
int currentPos;
yourViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Empty method
}
@Override
public void onPageSelected(int position) {
// This is paused fragment.
final Fragment pausedFragment = yourAdapter.getRegisteredFragment(currentPos);
// update current position value
currentPos = position;
// This is resumed fragment
final Fragment resumedFragment = yourAdapter.getRegisteredFragment(currentPos);
}
@Override
public void onPageScrollStateChanged(int state) {
// Empty method
}
});
最后,为了恢复实例状态,请更新当前位置,以便更新用户离开的位置ViewPager
currentPos = yourViewPager.getCurrentItem();
解决方案2:
对于其他解决方案,您可以ViewPager
找到Fragments
Tag
。您可以使用以下代码生成代码:
@NonNull
public static String generateViewPagerFragmentTag(int viewPagerId, int position) {
final StringBuilder tagBuilder = new StringBuilder();
tagBuilder.append("android:switcher:");
tagBuilder.append(viewPagerId);
tagBuilder.append(":");
tagBuilder.append(position);
return tagBuilder.toString();
}
找到你的Fragment
:
final Fragment yourFragment = getSupportFragmentManager().findFragmentByTag(generateViewPagerFragmentTag(R.id.your_viewpager, currentPos));
编辑:几年前,当我正在寻找获取ViewPager当前项目的解决方案时,我在UserVisibleHint
中尝试了Fragments
并注意到它不可靠。我不确定它现在是否可靠但我仍然避免使用。
答案 4 :(得分:2)
您可以在Fragment
public void setUserVisibleHint(boolean isVisibleToUser){
}
当isVisibleToUser == true
时,片段显示
答案 5 :(得分:1)
当前版本的ViewPager
库允许立即启用所需的行为,只需将second argument的FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT
传递给FragmentPagerAdapter。
还可以考虑使用ViewPager2来代替ViewPager
。默认情况下,ViewPager2
会调用onPause()
和onResume()
,不需要进行配置。
有关更多详细信息,请参见this answer。
答案 6 :(得分:0)
派对有点晚了,但是在我当前的应用程序中,我为我的viewpager设置了OffScreenPageLimit为1,这意味着片段没有被缓存,每次视图更改时都会重新加载当前片段
答案 7 :(得分:0)
为savepopulation答案中的方法提供更多定义:
yourPager.setOnPageChangeListener(new GridViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int row, int column, float rowOffset, float columnOffset, int rowOffsetPixels, int columnOffsetPixels) {
}
@Override
public void onPageSelected(int row, int column) {
// When on page selected if position is not specific for you
// you can find your fragment or you can switch position.
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
答案 8 :(得分:0)
经过研究,我找到了完美的解决方案。
初始化适配器时,请按照以下步骤操作:-
import static androidx.fragment.app.FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT;
//(i am using androidx but if you have not yet migrated yet you can use appcompat)
adapter = new FeedTabsPagerAdapter(getSupportFragmentManager(), BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT);
添加此行后,您将完美地获得onResume()和onPause回调。如果我的代码解决了此问题,请标记为正确的解决方案。干杯!