くらげになりたい。

くらげのようにふわふわ生きたい日曜プログラマなブログ。趣味の備忘録です。

Android: 画面サイズよりも大きいViewを縦/横/斜めでスクロールする

Androidで画像など、画面よりも大きいサイズのViewをドラッグでぐりぐりしたくて、
いろいろ調べてみたときの備忘録。

いくつか方法があるけど、
基本はScrollViewHorizontalScrollViewを両方使う感じ。

XML

XMLはこんな感じ。
ScrollViewwカスタマイズした、NestedScrollViewについては次に記載。

<NestedScrollView android:layout_width="fill_parent" android:layout_height="fill_parent">
  <HorizontalScrollView android:layout_width="fill_parent" android:layout_height="fill_parent">
    <ImageView />
  </HorizontalScrollView>
</NestedScrollView>

ScrollViewHorizontalScrollViewを両方使うと、
上下/左右にスクロールできるようになるけど、斜めとかグリグリはできない。

ScrollViewHorizontalScrollViewのどちらか一方でしか
TouchEventをハンドリングできないので、
両方で扱えるようにScrollViewをカスタマイズする必要がある。

NestedScrollView: ScrollViewをカスタマイズ

カスタマイズした内容はこんな感じ。

package com.study.app.ui;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ScrollView;

public class NestedScrollView extends ScrollView {

    public NestedScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public NestedScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NestedScrollView(Context context) {
        super(context);
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        // 子要素からTouchEventが抑止されないように、何も処理しない
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        onTouchEvent(ev); // TouchEventを子へ伝播させるため、自分でonTouchEventを処理
        return false; // 常に子へ伝播する
    }
}

TouchEventが親から子に伝播されない or 子から親を抑止されるため、
斜めに移動できないので、同時にonTouchEventを処理できるように拡張。

これで、いい感じにぐりぐりできるようになる。

他の方法として、ActivityでonTouchEventを処理し、自分でスクロールする方法もあるが、
それだと慣性スクロールを自前で実装しないといけない。。

以上!!

参考にしたサイト様