滑动时 ViewPager 更新片段 [英] ViewPager update fragment on swipe

查看:32
本文介绍了滑动时 ViewPager 更新片段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个问题,过去 2 天我一直在努力解决.

i have a problem that i have been struggling with for the past 2 days.

我正在构建一个使用 ActionBar、ViewPager 和片段页面适配器.Activity、Fragments & 的代码FragmentPagerAdapter 与 http://developer.android 上的 android 示例中所述完全相同.com/reference/android/support/v4/view/ViewPager.html

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

我面临的问题是——假设我在 viewPager 中只有 2 个片段.在两者之间切换/滑动时,片段没有得到更新.onResume 不会被调用,因为 viewPager 在显示的片段的任一侧缓存了至少 1 个片段.

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.

我尝试使用 onTabSelected 来检测何时选择了一个片段,然后在接口的帮助下从该片段启动一个方法(下面的代码).

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).

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();
}

但是,当使用 Start 方法时,尝试更新文本视图时会触发 NullPointerException.启动方法的代码是:

However, when the Start method is used a NullPointerException is fired when trying to update a textview. The start method's code is:

public void Start() {
    TextView tv = _view.findViewById(R.id.text);
    tv.setText("test");
}

在以下行抛出异常:

TextView tv = _view.findViewById(R.id.text);

IStartStop 接口非常简单:

The IStartStop interface is quite simple:

public interface IStartStop {
    public void Start();
    public void Stop();
}

我不想使用 notifyDataSetChanged();使用 POSITION_NONE 因为每次我滑动到新片段时,加载片段需要几秒钟

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

此时的fragment只包含一个textview,以后会有动画,所以很重要:

At this time, the fragments only include a textview, in the future they will have an animation and so it is important to:

1- 仅在选择片段时运行动画,而不是在选择它旁边的片段时运行动画(ViewPager 缓存和恢复片段的方式).

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).

2- 当片段不再被选中时停止动画以避免浪费设备资源.

2- Stop the animation when the fragment is no longer selected to avoid wasting device resources.

是的,我已经检查了互联网上的所有可用内容,但似乎没有任何东西适合我.

Yes, i already checked everything available on the internet but nothing seems to work with me.

非常感谢您的帮助!

推荐答案

令人惊讶的是,ViewPager 并没有原生地"执行此操作(除其他外).但并非全部丢失.

Surprisingly the ViewPager doesn't do this "natively" (among other things). But not all is lost.

首先,您必须修改片段,以便它们仅在您告诉它们可以运行时才运行动画,而不是在它们被实例化时运行.通过这种方式,您可以使用 viewpager 偏移量(默认 = 3)并预加载 2-3 个片段但没有动画.

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.

第二步是创建一个接口或类似的接口来定义片段何时变得可见".

Second step is to create an interface or similar that defines when the "fragment has become visible".

第三步是将一个新的 OnPageScrollListener 附加到您的 viewpager.

Third step would be to attach a new OnPageScrollListener to your viewpager.

代码如下(半未经测试的代码):

Code follows (in semi-untested-code):

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) 这是你的界面:

public interface YourFragmentInterface {
    void fragmentBecameVisible();
}

3) 更改您的片段,以便它们实现此功能:

3) Change your fragments so they implement this:

public class YourLovelyFragment extends Fragment implements YourFragmentInterface {

4) 在片段中实现接口

4) Implement the interface in the 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.
}

从这里到哪里去?

您可能希望实现一种方法/侦听器来通知其他"片段它们不再可见(即,当一个片段可见时,其他片段不可见).但这可能不是必需的.

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.

这篇关于滑动时 ViewPager 更新片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆