14

を使用しPagerAdapterます。要素がたくさんあるので、すべての要素を同時にロードすることはありません。アダプターをリロードし、古い要素を新しい要素で変更します。たとえば、4 つの要素があり、最後の要素に到達したら、要素をリロードしsetCurentItem(1)、viewpager を位置 1 に表示できるように呼び出します。私は多くのテストを行いました。置いた:

viewPager.setCurrentItem(1,false); //But not scroll, put drastically the new page.
viewPager.setCurrentItem(1);

を変更しようとしましたがonPageScrollStateChanged(int arg0)、ビューが 3 つしかなく、常に途中で ubicate します。

if (arg0 == ViewPager.SCROLL_STATE_DRAGGING) {
    if(focusedPage==2) {
        //Modify adapter
        viewPager.setCurrentItem(1,false);   

    }else if(focusedPage==0){
        //Modify adapter
        viewPager.setCurrentItem(1,false);
    } 

そして、私は変更しようとしましたonPageSelected(int arg0)

focusedPage=arg0;

この最後の例を使用すると、ビューをすぐにスクロールできますが、常に最後のページに配置されます。私が滑る方法を知っている人は誰でも。

ありがとうございました

4

2 に答える 2

53

あなたが成し遂げようとしていることの背景についてもっと知りたいですか?

とにかく、私が理解できることから、あなたは最後のものから最初のものへ、そしてその逆に「無限」を行おうとしていると理解できますViewPager(私が間違っている場合は私を訂正してください)。そしてViewPager、最初のページに移動してスクロールする必要があります。どこからともなく表示されるだけではありません。

さて、スムーズスクロール(2番目のパラメーター)を無効にすると、スクロールモーションなしで目的のページに直接移動し(途中で他のページに「変更」されません)、スムーズを有効にするとスクロールすると、すべてのビューが表示されるので、次のビューではなく最初のビューがどのように表示されたかがわかります。

    /*No swipe animation, and no onPageChanged for the page in the middle*/
    mPager.setCurrentItem(1, false); 

    /*The same as if you do not add the second parameter*/
    mPager.setCurrentItem(1, true);

    /*Your ViewPager scrolls through all the needed views until it arrives at that view.*/
    mPager.setCurrentItem(1);

これを念頭に置いて私がお勧めできるのは、位置0と「最後」に「ダミー」ビューを追加してみて、位置0のビューが位置「最後-1」と「最後」と同じになることです。ビューは位置「1」と同じになります。したがって、OnPageChangeListenerで現在のページが「0」または「最後」の位置にあるかどうかを確認し、そうである場合はsetCurrentItem( "1"、false)またはsetCurrentItem( "lastを呼び出すことを除いて、通常どおりにすべてを実行します。 --1 "、false)現在の位置によって異なります。このようにして、あなたはあなたが望むことを達成している間、あなたは「ページ変更」効果を維持するでしょう。

これがあなたの問題に役立つことを願っています。

注: 新しい位置に到着した後、現在、次、最後のビューのビューをロードする必要があるため、変更が遅れる場合があります(または、4.0以降を使用している場合は、実際の位置のみがロードされます)。

アップデート:

の内容を決定するリスト/配列の内容を変更する場合は、ViewPager以下を呼び出す必要があります。

ViewPager mPager = new ViewPager();
mPager.getAdapter().notifyDataSetChanged();  //This notify that you need to recreate the views

/*This is if you want to change the data and then go to a specific position
If you do not do this you will have a very Buggy Behavior*/
new Handler().post(new Runnable() {
@Override
public void run() {
    mPager.setCurrentItem(2); //Where "2" is the position you want to go
    }
});

更新2:

すべての要素をに追加しないのはなぜViewPagerですか?すでにそれらのケースを処理するためのViewPager最適化があります。私の場合、私はそれに多くの要素を持っており、それは魅力のように機能しています。

もう1つ、コードでは、ページが「落ち着く」たびに中央のページに移動するのがわかります。しかし、実際には左右のビューを表示することはありません。なぜそれらを持っているのでしょうか。

最後に、データセットを変更するときは、前述の「notifyDataSetChanged」メソッドを呼び出してから、ハンドラー内で「setCurrentItem」メソッドを呼び出す必要があります。そうしないと、アプリは期待どおりに機能しません。

更新3:

さて、私がお勧めできる唯一のことは、データベースから持ってきた新しいオブジェクトを追加し続けるリストを用意することです。そして、リストの最後にオブジェクトを挿入し続ける限り、問題はありません。途中または最初にオブジェクトを追加する場合は、notifyDataSetChangedを呼び出す必要がありますが、ビューが再度生成されるため、少し時間がかかります。私たちはこの方法でそれを行い、それは完璧に機能し、サーバーから情報をダウンロードすることさえあります。データはローカルではありません(そして実際にはリストの最後と最初に情報を追加します)。

これを達成する方法について他に質問がある場合は、遠慮なく質問してください。

更新4:

誰かが実際にサーキュラーを探している場合に備えて、再利用できる概念実証コードViewPagerを追加しました。それは問題なく動作し、私はそれを複雑なビューで使用しましたが、それでもラグはまったくありません。

于 2012-08-20T22:47:53.373 に答える
3

postDelayed なしでは機能しません。次のコードを試してください。

viewPager.postDelayed(new Runnable()
{
    @Override
    public void run()
    {
        viewPager.setCurrentItem(num, true);
    }
}, 100);
于 2016-09-15T21:24:17.677 に答える