web-dev-qa-db-ja.com

スワイプ時のViewPager更新フラグメント

過去2日間苦労している問題があります。

ActionBar、ViewPager、FragmentPagerAdapterを使用するアプリを作成しています。 Activity、Fragments、およびFragmentPagerAdapterのコードは、 http://developer.Android.com/reference/Android/support/v4のAndroidの例に記載されているものとまったく同じです。 /view/ViewPager.html

私が直面している問題は、viewPagerにフラグメントが2つしかないことを前提としています。 2つの間で切り替え/スワイプするとき、フラグメントは更新されません。 viewPagerは、表示されたフラグメントのいずれかの側に少なくとも1つのフラグメントをキャッシュするため、onResumeは呼び出されません。

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

ただし、テキストビューを更新しようとすると、Startメソッドが使用されるとNullPointerExceptionが発生します。 startメソッドのコードは次のとおりです。

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

次の行で例外がスローされます。

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

IStartStopインターフェイスは非常にシンプルです。

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

NotifyDataSetChanged();を使用したくありません。 POSITION_NONEを使用すると、新しいフラグメントにスワイプするたびに、フラグメントのロードに数秒かかるため

現時点では、フラグメントにはテキストビューのみが含まれており、将来的にはアニメーションを持つため、次のことが重要です。

1-フラグメントが選択されているときのみアニメーションを実行し、その隣のフラグメントが選択されているときは実行しません(ViewPagerがフラグメントをキャッシュおよび再開する方法)。

2-フラグメントが選択されなくなったら、アニメーションを停止して、デバイスリソースの浪費を防ぎます。

はい、私はすでにインターネット上で利用可能なすべてをチェックしましたが、何も私と一緒に動作しないようです。

手伝ってくれてありがとうございます!

27
Steve

驚くべきことに、ViewPagerは(特に)これを「ネイティブに」行いません。しかし、すべてが失われるわけではありません。

最初に、インスタンス化されたときではなく、大丈夫だと伝えるときにのみアニメーションを実行するように、フラグメントを変更する必要があります。この方法で、ビューページャーオフセット(デフォルト= 3)で再生し、2〜3個のフラグメントをプリロードすることができますが、アニメーション化することはできません。

2番目のステップは、「フラグメントが表示されるようになったとき」を定義するインターフェースなどを作成することです。

3番目のステップは、新しいOnPageScrollListenerをビューページャーにアタッチすることです。

コードは次のとおりです(テストされていないコード):

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)フラグメントを変更して、これを実装します:

public class YourLovelyFragment extends Fragment implements YourFragmentInterface {

4)フラグメントにインターフェースを実装する

@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.
}

ここからどこへ行きますか?

メソッド/リスナーを実装して、「他の」フラグメントに表示されなくなったことを通知することができます(つまり、一方が表示されたときに、もう一方は表示されません)。しかし、それは必要ないかもしれません。

55

これは、ページャーの表示のあるページから別のページへの変更に影響します。

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

これをページアダプタで使用します。

@Override
    public int getItemPosition(Object object) {

        return POSITION_NONE;
    }
4
Dinesh IT

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) {
        }
    });
2
A. Vin