ViewPagerで最終ページ・先頭ページの行き来について

6,411 views
Skip to first unread message

marimo

unread,
Oct 22, 2012, 4:58:32 AM10/22/12
to android-g...@googlegroups.com
お世話になっております。岩橋と申します。

ViewPagerを使用してページ切り替えの対応を行っており
件名の通り
 最終ページで右フリック ⇒ 先頭ページへ遷移
 先頭ページで左フリック ⇒ 最終ページへ遷移

上記2つの操作を実現して、ループしたみたいに遷移し続ける方法を実現したいと思っております。

ViewPagerのソースを色々と見て試行錯誤しているのですが
上記状態のフリックはできないように見え、路頭に迷ってます。
何かよい方法はないでしょうか。

例えば、1~100ページで実現する場合
ダミーページを1ページ分用意(PagerAdapter#getCountは101)したりと考えたのですが
追従する動きにはついていけないだろうと。。

何度もご相談させて頂いて恐縮なのですが
気づいた点でも何でも結構ですのでアドバイス頂けると幸いです。

※やりたいこと
・画面遷移の動きはまさしくViewPagerと同じです
 →フリック中は、前頁と次頁が切り替わる状態
・先頭,最終頁で行き来したい
これができれば、ViewPagerでなく他の方法でもよいのですが
他に見つけきれておりません。。



以上、よろしくお願い致します。

Shigeo Mutoh

unread,
Oct 22, 2012, 10:35:49 PM10/22/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

見当はずれかも知れませんが。。

ViewPagerは使ったことがないのですが、先日ViewFlipperを使ったときに、
特に意識的に設定しなくても、最終ページと先頭ページがループした遷移
をしました。

marimo

unread,
Oct 23, 2012, 12:16:15 AM10/23/12
to android-g...@googlegroups.com
武藤様

いつもお世話になっております。岩橋です。

投稿ありがとうございます!!!

ViewFlipperのソースではshowNext,showPreviewの中で
次に進む画面が
 先頭の前画面 ⇒ 最終ページに移動
 最終の次画面 ⇒ 先頭ページに移動
と切り替えてくれているようです。

確かにこれだと助かるのですが・・
ただ、ViewFlipperだとドラッグの動きに沿って移動するようなこともできるのでしょうか。
(指に追従する形)

お忙しいところ恐れ入りますがご教示頂けると幸いです。



2012年10月23日火曜日 11時36分25秒 UTC+9 TM:

Shigeo Mutoh

unread,
Oct 23, 2012, 1:03:02 AM10/23/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

ViewFlipperは指の動きに追従しないです。フリック操作完了後に
遷移し始めます。

実は「指の動きに追従する」ようにしたいと思っていたので、
私もViewPagerを使ってページ遷移のループ化の方法は知りたい
ところです。

ソースをよく読まれているようですから、ViewPagerをsubclassing
して、必要なメソッドをoverrideして動きを変えることで実現でき
ませんか?

Shigeo Mutoh

unread,
Oct 23, 2012, 2:44:19 AM10/23/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

適当なこと言ってしまいすみません。自分でも一応ソースぐらい
眺めておこうと思って、見てたらこれは駄目そうだと思いました。

たぶん、次のページはどこかを決めているのは、ViewPagerの
determineTargetPage()ですよね? こいつがprivateなんで、
無理っぽいと思いました。

こんな感じで上がってきてます。
ViewPager.determineTargetPage(int, float, int, int) line: 1918
ViewPager.onTouchEvent(MotionEvent) line: 1773
ViewPager(View).dispatchTouchEvent(MotionEvent) line: 5541

で、onTouchEvent()の中ではACTION_UPのときdetermineTargetPage()は
呼ばれているので、最終的な目的地としてのページ番号の決定が、
もはや変えようがないということで、どのみちoverride程度じゃあ
駄目だという結論です。

なので、最終的には自作するしかなさそうなのですが、少なくとも
ViewPagerはApache Licence2.0なので自由に改変してよろしいかと
思います。是非頑張ってください。(そしてそれくださーい!)


marimo

unread,
Oct 23, 2012, 4:34:18 AM10/23/12
to android-g...@googlegroups.com
お世話になっております。岩橋です。

色々とありがとうございます!!

できれば、提供されている部品を流用したほうが理想だったのですが
やはりViewPagerをカスタマイズしたほうが有効でしょうか。

ViewPagerをカスタマイズする方向でも検討してみます。

ただ、私事の都合で申し訳有りませんが時間的に厳しい部分もあるため
他の方法でも何かよい案があれば
引き続きアドバイス頂けると助かります。 ->武藤さま、みなさま


以上、よろしくお願い致します。


2012年10月23日火曜日 15時44分59秒 UTC+9 TM:

Yuki Anzai

unread,
Oct 23, 2012, 4:40:55 AM10/23/12
to android-g...@googlegroups.com
あんざいです。

 実質的には 3ページだけもって(PagerAdapter の getCount() の戻りが3)、
 常に2番目のページを表示するように、画面切り替わりのタイミングで
 ページの位置を戻します。
 また、内部で表示する View (または Fragment)の一覧を別途もっておいて
 画面切り替わりのタイミングでそれも切り替えます。
 こうすると実現できます。

 コードは載せられないのでがんばって実装してください。


2012/10/23 marimo <marim...@gmail.com>:
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msg/android-group-japan/-/dRBqjMOxStAJ
> にアクセスしてください。
>
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com
> にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
> からこのグループにアクセスしてください。



--
あんざい ゆき
anzai...@gmail.com
twitter : @yanzm
Y.A.Mの雑記帳 http://y-anz-m.blogspot.com/

Shigeo Mutoh

unread,
Oct 23, 2012, 4:50:31 AM10/23/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

今たばこ吸って思いついたのに、一歩遅れました。
すごく悔しいです。

marimo

unread,
Oct 23, 2012, 5:15:38 AM10/23/12
to android-g...@googlegroups.com
お世話になっております。岩橋です。


ありがとうございます!!!

以下の通り理解したのですが、認識は合ってますでしょうか。


>実質的には 3ページだけもって(PagerAdapter の getCount() の戻りが3)、
>常に2番目のページを表示するように、
>画面切り替わりのタイミングで
>ページの位置を戻します。

「画面切り替わりのタイミングで」というのは
 ViewPager.onPageChangeListener#onPageScrollStateChangeで
 引数の値がSCROLL_STATE_DRAGGING

のタイミングじゃないかと思いました。


>また、内部で表示する View (または Fragment)の一覧を別途もっておいて
>画面切り替わりのタイミングでそれも切り替えます。
>こうすると実現できます。

はい。ちょうど今も保持しておりました。

毎回、ViewPagerのpositionは1を表示するように設定して、
0,1,2のpositionが実際の何ページにあたるのかを自分で覚えておいて
PageAdapter#instantiateItemで、対応するViewを一覧から取得して返却する
ような流れでしょうか。

自分の頭の切り替えの鈍さに参りました。。

お忙しいところご面倒をおかけして申し訳有りませんが
再度、ご確認頂けると助かります。

以上、よろしくお願い致します。

2012年10月23日火曜日 17時43分19秒 UTC+9 Yuki Anzai:
> このグループに投稿するには、android-group-ja...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-japan+unsubscribe@googlegroups.com

marimo

unread,
Oct 23, 2012, 5:16:27 AM10/23/12
to android-g...@googlegroups.com
ありがとうございます!!

皆さんのおかげで段々とイメージがクリアになってきました。
本当に助かります。


2012年10月23日火曜日 17時50分59秒 UTC+9 TM:
tmhouseこと武藤です。

今たばこ吸って思いついたのに、一歩遅れました。
すごく悔しいです。

MORIHIRO

unread,
Oct 23, 2012, 5:46:51 AM10/23/12
to android-g...@googlegroups.com
イメージは下記のサイトの一番下にある方法だと思います。
→ 3ページでとっかえひっかえする案なので別物かも。。。
  http://stackoverflow.com/questions/10188011/how-to-make-a-viewpager-loop

ただ、これを自分で試した感じではページの位置を戻したタイミングで画面が
ちらつく感じでイマイチ、、、でした(私の実装に問題ありの可能性大ですが)。

以上、ご参考まで。

2012年10月23日火曜日 18時15分38秒 UTC+9 marimo:

Shigeo Mutoh

unread,
Oct 23, 2012, 7:10:35 AM10/23/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

一応作ったのでソース添付します。

ただしあまりメモリのことは考えてないので、上司がバカなら
いいんですが、そうじゃないなら改良が必要かも知れません。

では。

MainActivity.java
LoopedViewPager.java

Makoto Yamazaki

unread,
Oct 23, 2012, 7:31:48 AM10/23/12
to android-g...@googlegroups.com
zaki です。

ViewPager loop で検索してみたところ StackOverflow のエントリがヒットしました。

http://stackoverflow.com/questions/10188011/how-to-make-a-viewpager-loop
http://stackoverflow.com/questions/8239056/implementing-circular-scrolling-in-pageradapter

私は試してないのでうまくいくかわかりませんが参考まで。

2012/10/23 marimo <marim...@gmail.com>:
> --
> このメールは Google グループのグループ「日本Androidの会」の登録者に送られています。
> このディスカッションをウェブ上で閲覧するには、https://groups.google.com/d/msg/android-group-japan/-/dRBqjMOxStAJ
> にアクセスしてください。
>
> このグループに投稿するには、android-g...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-j...@googlegroups.com
> にメールを送信してください。
> 詳細については、http://groups.google.com/group/android-group-japan?hl=ja
> からこのグループにアクセスしてください。



--
YAMAZAKI Makoto

Shigeo Mutoh

unread,
Oct 23, 2012, 9:10:17 AM10/23/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

こっちの方がアニメーションがうまく動くのと、岩橋さんの上司が
バカではないと仮定した場合の対応をしました。

私のテストでは非常にうまく動いています。

LoopedViewPager.java

marimo

unread,
Oct 23, 2012, 9:38:27 AM10/23/12
to android-g...@googlegroups.com
ありがとうございます。

実際にコードを書いてみます。


2012年10月23日火曜日 18時46分51秒 UTC+9 MORIHIRO:

Shigeo Mutoh

unread,
Oct 24, 2012, 5:45:33 AM10/24/12
to android-g...@googlegroups.com
tmhouseこと武藤です。

たびたびすみませんが、これで終わりだと思います。

ページ総数が0, 1, 2のときを考慮してませんでしたので
直した版を添付しました。

あと、今後誰かが直してくれるかも知れないことを期待して、
未解決の問題も示しておきます。

・スクロール完了直後の動作がもっさりしている
onPageScrollStateChanged()でpostしているRunnableは、
そうしないとアニメーションがカクついたりビカるからで、単に
遅延処理です。そして遅延後のreset()内で行われている
ViewPager.setAdapter()が重いようで、連続した高速スクロールは
もっさりカクつき感が漂います。だから今から思えば、setAdapterが遅い
ならば頻繁にそれを呼ばないよう改修したいところです。
たぶん、PagerAdapter.getCount()が返す値をsigned intの最大値
にして、初期表示ページはそれの半分のところにして、instantiateItem()
はpositionを実際の総ページ数で剰余すればうまくいくと思っています。
今より実装は綺麗になると思います。

以上です。

MainActivity.java
LoopedViewPager.java

marimo

unread,
Oct 24, 2012, 8:59:47 PM10/24/12
to android-g...@googlegroups.com
お世話になっております。岩橋です。

ありがとうございます!!!!
ソース見させて頂きます。

まだViewPagerのカスタマイズ以外の方法はないかとも模索しておりますが・・
頂いたソース等を参考に引き続き検討します。



2012年10月24日水曜日 18時46分21秒 UTC+9 TM:

marimo

unread,
Oct 24, 2012, 9:01:56 PM10/24/12
to android-g...@googlegroups.com
お世話になっております。岩橋です。

ありがとうございます!!

はい。。
私も参考に実装したところ、setCurrentItemのタイミングでちらつきます。。

もう少し検討してみます。


2012年10月23日火曜日 18時46分51秒 UTC+9 MORIHIRO:

marimo

unread,
Oct 24, 2012, 9:03:47 PM10/24/12
to android-g...@googlegroups.com
お世話になっております。岩橋です。

ありがとうございます!!
皆さん同じことをトライされているんですね・・。

頂いた情報を元に、トライされている内容を確認します。

2012年10月23日火曜日 20時32分46秒 UTC+9 zaki:
> このグループに投稿するには、android-group-ja...@googlegroups.com にメールを送信してください。
> このグループから退会するには、android-group-japan+unsubscribe@googlegroups.com

Shigeo Mutoh

unread,
Oct 29, 2012, 11:47:56 AM10/29/12
to android-g...@googlegroups.com
tmhosueこと武藤です。

(12/10/24 18:45), Shigeo Mutoh wrote:
> たぶん、PagerAdapter.getCount()が返す値をsigned intの最大値
> にして、初期表示ページはそれの半分のところにして、instantiateItem()
> はpositionを実際の総ページ数で剰余すればうまくいくと思っています。

のちに、最初に表示するページを任意のページに設定したいという動機
があって、以前のコードを改修しようとすると気が狂いそうになったため、
上記で構想したとおりに実装し直しました。
くどくて申し訳ないですが添付しておきます。

今回の実装の方が綺麗で断然速いです。

なお、10億回ほど一方向にスクロールし続けると、ViewPagerの基本的
振る舞いのように、壁にぶつかったような動きになるハズです。
ただしこれを人力でやると、寝ずに毎秒スクロールしても何十年かかかると
思いますが..。

TmLoopedViewPager.java
Reply all
Reply to author
Forward
0 new messages