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 件のコメント:
コメントを投稿