web-dev-qa-db-ja.com

Infinite ViewPager

これは可能のようですが、無期限にページングできるViewPagerを実装する方法を理解するのに少し問題があります。

私のユースケースは、一度に1か月を表示するカレンダーですが、十分な回数ページングすることで任意の月に切り替えることができます。

現在、私はextending PagerAdapter、および3つのカスタムMonthViewsが次のように追加されます。

    @Override
    public Object instantiateItem(View collection, int position) {
        final MonthView mv = new MonthView(HistoryMonthActivity.this);
        mv.setLayoutParams(new ViewSwitcher.LayoutParams(
                Android.view.ViewGroup.LayoutParams.MATCH_PARENT,
                Android.view.ViewGroup.LayoutParams.MATCH_PARENT));
        mv.setSelectedTime(mTime);

        ((DirectionalViewPager) collection).addView(mv, 0);

        return mv;
    }

ユーザーがタブを使用しているときに各MonthViewにデータベースからのデータを表示するのに大きな遅延がないように、一度に3つのMonthViewsだけをメモリに保持したいと思います。したがって、新しいページが表示されるたびに、1つのMonthViewを削除し、1つのMonthViewを追加する必要があります。誰かが同じ機能についてより良いアイデアを持っているなら、私はそれを聞いてみたいです!

FragmentStatePagerAdapterを使おうと思っています。

19
Jon Willis

MonthViews、PagerAdapterOnPageChangeListenerにちょっとした魔法を使って、またViewPager自体のソースコードを編集して、これを実装することができました。誰かが私がそれをどのように達成したかに興味があるなら、 ソースコードをチェックしてください または特定の質問でコメントしてください。

8
Jon Willis

実際、私はこの「無限の」ページ付けを行うためのさまざまな方法を検討してきました。人間の時間の概念は無限であるということですが(時間の始まりと終わりの概念はありますが)、コンピューターはディスクリートで。最小時間と最大時間があります(時間の経過とともに調整できます。Y2K問題の根拠を覚えていますか?)。

とにかく、この議論のポイントは、実際には有限の日付範囲を通じて比較的無限の日付範囲をサポートするのに十分である/必要があるということです。この良い例は、AndroidフレームワークのCalendarView実装とその中のWeeksAdapterです。デフォルトの最小日は1900年で、デフォルトの最大日はです。 2100年には、これは、今日の半径10年以内の人のカレンダー使用の99%を簡単にカバーするはずです。

彼らが実装で行うこと(週に焦点を当てる)は、最小日と最大日の間の週数を計算することです。これがポケットベルのページ数になります。ページャーはこれらすべてのページを同時に維持する必要はなく(setOffscreenPageLimit(int))、ページ番号(またはインデックス/位置)に基づいてページを作成できる必要があることに注意してください。この場合、インデックスは、その週が最小日からの週数です。このアプローチでは、最小の日付とページ数(最大の日付までの距離)を維持するだけで、どのページについても、そのページに関連付けられている週を簡単に計算できます。 ViewPagerがループ(別名、無限のページ付け)をサポートしていないという事実をめぐって踊ることはなく、無限にスクロールできるように強制的に動作させようとします。

new FragmentStatePagerAdapter(getFragmentManager()) {
    @Override
    public Fragment getItem(int index) {
        final Bundle arguments = new Bundle(getArguments());
        final Calendar temp_calendar = Calendar.getInstance();
        temp_calendar.setTimeInMillis(_minimum_date.getTimeInMillis());
        temp_calendar.setFirstDayOfWeek(_calendar.getStartOfWeek());
        temp_calendar.add(Calendar.WEEK_OF_YEAR, index);
        // Moves to the first day of this week
        temp_calendar.add(Calendar.DAY_OF_YEAR,
                -UiUtils.modulus(temp_calendar.get(Calendar.DAY_OF_WEEK) - temp_calendar.getFirstDayOfWeek(),
                7));
        arguments.putLong(KEY_DATE, temp_calendar.getTimeInMillis());
        return Fragment.instantiate(getActivity(), WeekDaysFragment.class.getName(), arguments);
    }

    @Override
    public int getCount() {
        return _total_number_of_weeks;
    }
};

次に、WeekDaysFragmentは、引数で渡された日付から始まる週を簡単に表示できます。

6
Dandre Allison