Android 滑动时 ViewPager 更新片段
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20412379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ViewPager update fragment on swipe
提问by Steve
i have a problem that i have been struggling with for the past 2 days.
我有一个问题,过去 2 天我一直在努力解决。
I am building an app that uses ActionBar, ViewPager & FragmentPagerAdapter. The code for the Activity, Fragments & FragmentPagerAdapter are exactly as the ones stated in the android example on http://developer.android.com/reference/android/support/v4/view/ViewPager.html
我正在构建一个使用 ActionBar、ViewPager 和 FragmentPagerAdapter 的应用程序。Activity、Fragments 和 FragmentPagerAdapter 的代码与http://developer.android.com/reference/android/support/v4/view/ViewPager.html上的 android 示例中所述的代码完全相同
The problem i am facing is -- assuming i have only 2 fragments in the viewPager. when switching/swiping between the two, the fragments are not getting updated. onResume does not get called because the viewPager caches a minimum of 1 fragment to either side of the displayed fragment.
我面临的问题是——假设我在 viewPager 中只有 2 个片段。在两者之间切换/滑动时,片段不会更新。onResume 不会被调用,因为 viewPager 将至少 1 个片段缓存到显示片段的任一侧。
I tried using the onTabSelected to detect when a fragment is selected and then start a method from that fragment with the help of an interface (code below).
我尝试使用 onTabSelected 来检测何时选择了一个片段,然后在界面(下面的代码)的帮助下从该片段启动一个方法。
public void onTabSelected(Tab tab, FragmentTransaction ft) {
TabInfo tag = (TabInfo)tab.getTag();
for (int i=0; i<mTabs.size(); i++) {
if (mTabs.get(i) == tag) {
mViewPager.setCurrentItem(i);
}
}
((IStartStop)getItem(tab.getPosition())).Start();
}
However, when the Start method is used a NullPointerException is fired when trying to update a textview. The start method's code is:
但是,当使用 Start 方法时,尝试更新文本视图时会触发 NullPointerException。start方法的代码是:
public void Start() {
TextView tv = _view.findViewById(R.id.text);
tv.setText("test");
}
The exception is thrown at line:
异常在以下行抛出:
TextView tv = _view.findViewById(R.id.text);
The IStartStop interface is quite simple:
IStartStop 接口非常简单:
public interface IStartStop {
public void Start();
public void Stop();
}
I don't want to use notifyDataSetChanged(); with POSITION_NONE because every time I swipe to a new fragment, it takes a few seconds to load the fragments
我不想使用 notifyDataSetChanged(); 使用 POSITION_NONE 因为每次我滑动到一个新片段时,加载片段需要几秒钟
At this time, the fragments only include a textview, in the future they will have an animation and so it is important to:
此时,片段只包含一个文本视图,将来它们会有动画,因此重要的是:
1- Only run an animation when the fragment is selected and not when the fragment next to it is selected (the way ViewPager caches and resumes fragments).
1-仅在选择片段时运行动画,而不是在选择它旁边的片段时运行动画(ViewPager 缓存和恢复片段的方式)。
2- Stop the animation when the fragment is no longer selected to avoid wasting device resources.
2- 不再选择片段时停止动画以避免浪费设备资源。
Yes, i already checked everything available on the internet but nothing seems to work with me.
是的,我已经检查了互联网上可用的所有内容,但似乎没有任何效果。
Thank you very much for your help!
非常感谢您的帮助!
回答by Martin Marconcini
Surprisingly the ViewPager
doesn't do this "natively" (among other things). But not all is lost.
令人惊讶的是,ViewPager
它并没有“本地”执行此操作(除其他外)。但并不是所有的都丢失了。
First you have to modify your fragments so they only run the animation when you tell them that it's ok and not when they are instantiated. This way you can play with the viewpager offset (default = 3) and have 2-3 fragments preloaded but not animated.
首先,您必须修改您的片段,以便它们仅在您告诉它们没问题时才运行动画,而不是在实例化时运行。通过这种方式,您可以使用 viewpager 偏移量(默认值 = 3)并预加载 2-3 个片段但未设置动画。
Second step is to create an interface or similar that defines when the "fragment has become visible".
第二步是创建一个接口或类似的定义“片段何时变得可见”。
Third step would be to attach a new OnPageScrollListener to your viewpager.
第三步是将新的 OnPageScrollListener 附加到您的 viewpager。
Code follows (in semi-untested-code):
代码如下(在半未经测试的代码中):
1) Attach the Listener:
1)附加监听器:
mViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int i, final float v, final int i2) {
}
@Override
public void onPageSelected(final int i) {
YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
if (fragment != null) {
fragment.fragmentBecameVisible();
}
}
@Override
public void onPageScrollStateChanged(final int i) {
}
});
2) This is your Interface:
2)这是您的界面:
public interface YourFragmentInterface {
void fragmentBecameVisible();
}
3) Change your fragments so they implement this:
3)改变你的片段,让他们实现这一点:
public class YourLovelyFragment extends Fragment implements YourFragmentInterface {
4) Implement the interface in the fragment
4)在fragment中实现接口
@Override
public void fragmentBecameVisible() {
// You can do your animation here because we are visible! (make sure onViewCreated has been called too and the Layout has been laid. Source for another question but you get the idea.
}
Where to go from here?
然后去哪儿?
You might want to implement a method/listener to notify the "other" fragments that they are no longer visible (i.e. when one is visible, the others are not). But that may not be needed.
您可能想要实现一个方法/侦听器来通知“其他”片段它们不再可见(即,当一个片段可见时,其他片段不可见)。但这可能不需要。
回答by Dinesh IT
This will affect the changes from one page to another page in view pager.
这将影响视图寻呼机中从一个页面到另一个页面的更改。
OnPageChangeListener pagechangelistener =new OnPageChangeListener() {
@Override
public void onPageSelected(int arg0) {
Logger.logMessage("Called first");
pageAdapter.notifyDataSetChanged();
indicator.setCurrentItem(arg0);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
Logger.logMessage("Called second");
}
@Override
public void onPageScrollStateChanged(int arg0) {
Logger.logMessage("Called third");
}
};
myViewPager.setOnPageChangeListener(pagechangelistener);
Use this in your page adapter.
在您的页面适配器中使用它。
@Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
回答by A. Vin
setOnPageChangeListener has been deprecated. Instead, you should use addOnPageChangeListener.
setOnPageChangeListener 已被弃用。相反,您应该使用 addOnPageChangeListener。
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(final int i, final float v, final int i2) {
}
@Override
public void onPageSelected(final int i) {
YourFragmentInterface fragment = (YourFragmentInterface) mPagerAdapter.instantiateItem(mViewPager, i);
if (fragment != null) {
fragment.fragmentBecameVisible();
}
}
@Override
public void onPageScrollStateChanged(final int i) {
}
});
回答by FinalDark
Add this code when you define the Viewpager
定义 Viewpager 时添加此代码
mViewPager.setOffscreenPageLimit(0);
It will not save any view of the fragments when you switch to other fragment .. so switching from fragment to another will create the fragment from the start and update everything.
当您切换到其他片段时,它不会保存片段的任何视图..因此从片段切换到另一个片段将从头开始创建片段并更新所有内容。