2つを比べてみると、iPhoneでは最上部までスクロールしてもまだスクロールすることができるのに対し、Androidではコンテンツの最上部までスクロールしてしまうと、それ以上スクロールを試みてもうんともすんとも言わないといった違いがあり、これがストレスの原因の一つと思われる。
そこで、Androidでもびろーんってのを実装してみようと考えたわけだが、Androidでは簡単に実現する方法が見当たらない。※Android 2.3 (Gingerbread)ではOverscrollを使う簡単な方法があるらしい。
なので今回は、OverscrollをAndroid 2.2以下でも簡単に実装することができる方法を考えてみた。そんでもってついでに公開してみた。Google Codeにサンプルプロジェクトごと公開してみたので、興味があればご参照あれ。
まず、画面を構成する要素はScrollViewとその子要素(今回はLinearLayoutとした)である。ScrollViewは子要素を一つしか設定できない。子要素の中身には適当なViewを配置してみる。
<ScrollView android:id="@+id/scroll_view" android:layout_width="fill_parent" android:layout_height="fill_parent"> <LinearLayout android:id="@+id/content" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingTop="200dip" android:paddingBottom="200dip"> <TextView android:layout_width="fill_parent" android:layout_height="300dip" android:text="First Content." android:textSize="50dip"/> <TextView android:layout_width="fill_parent" android:layout_height="300dip" android:text="Second Content." android:textSize="50dip"/> <TextView android:layout_width="fill_parent" android:layout_height="300dip" android:text="Third Content." android:textSize="50dip"/> </LinearLayout> </ScrollView>
ScrollViewの子要素であるLinearLayoutには、OverScrollするための余白としてpaddingTopおよびpaddingBottomに200dipを設定しておく。
次にTouchEventListenerを作成し、ScrollViewへ登録する。
scrollView.setOnTouchListener(new MyOnTouchListener(scrollView, contentView));
TouchEventListenerではACTION_UPをフックし、ScrollViewのgetScrollY()メソッドで現在のスクロール位置を取得する。現在のスクロール位置がpadding領域であった場合は、画面の端にpadding領域を除いたContent部分がぴったり表示されるようにスクロールする。といった感じ。
多分、コードのほうがわかり易い。
@Override public boolean onTouch(View v, MotionEvent event) { scroller.forceFinished(true); mScrollView.removeCallbacks(task); if (event.getAction() == MotionEvent.ACTION_UP) { int displayHeight = mScrollView.getHeight(); int contentTop = mContentView.getPaddingTop(); int contentBottom = mContentView.getHeight() - mContentView.getPaddingBottom(); int lastPageTop = contentBottom - displayHeight; int currScrollY = mScrollView.getScrollY(); scroller.startScroll(0, currScrollY, 0, lastPageTop - currScrollY, 500); mScrollView.post(task); return true; } return false; }
ちなみに、scrollerはアニメーション付きのスクロール量計算をカプセル化したクラスで、下記のようなコードでインスタンスを生成しておく。
scroller = new Scroller(mScrollView.getContext(), new OvershootInterpolator());
また、taskの実体はRunnableであり、scrollerの計算結果取得とScrollView#scrollTo()メソッドの呼び出しを行っている。
task = new Runnable() { @Override public void run() { scroller.computeScrollOffset(); mScrollView.scrollTo(0, scroller.getCurrY()); if (!scroller.isFinished()) { mScrollView.post(this); } } };
結果はこれ。
画像だと伝わりにくいが、タッチして下へぐぐっと引っ張ることができる。
指をはなすとびろーんアニメーション(Overshoot)でもとに戻る。
0 件のコメント:
コメントを投稿