うにそんのブログ

ITやバイクや音楽について書いていこうと思います

【AndroidStudio】ScrollViewで横フリックイベントを使う

こんにちは、うにそんです。

 

今とある画像のviewerアプリ作っています。

それで、今まさに画像のViewer部分実装中なのです。

機能としては、「横にフリックすると次の画像を表示し、縦にフリックすると画面をスクロールして表示中の画像の下の部分を表示する」みたいな。

 

そこで標題の件です。

縦スクロールするためにScrollVeiwの中にImageViewを入れました。

そしてスクロールできることを確認して、フリックしたら次の画像へーって処理をonTouchEventで実装。

が、ここで問題発覚、onTouchEventが呼ばれない。

 

調べて見るとこんな記事が

turtle2005.blog.so-net.ne.jp

 

なんだかよく分からないけど、スクロールってそもそもフリックが必要なのに、同じScrollViewの上で横フリック実装しようとしてるのがいけないみたい。

多分フリックした時のイベントをScrollViewに取られちゃってるんでしょうね(適当)

 

で、もうちょっと調べてるとこんな記事

yamato-iphone.blogspot.jp

 

うーん相変わらずよく分からないが、onTouchEventの代わりにdispatchTouchEventを使えばいけるそうな。

やってみたら、横フリック動きました。

しかし今度はスクロールができない。

そりゃそうだ、今までScrollViewが使ってたタッチイベントを横フリックが奪ってしまったんだもの。

ということで、どうしたものかとさんざん悩みましたが、最終的にdispatchTouchEventの先で、縦フリックか横フリックか判断して、たてフリックだったらスクロールする!みたいな処理入れたらいけました。

ソースコードはこんな感じ

 

// タッチイベント
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
Log.d("","dispatchTouchEvent");
return mGestureDetector.onTouchEvent(event);
}

// タッチイベントのリスナー
private final GestureDetector.SimpleOnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() {

// フリックイベント
@Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) {

try {

// 移動距離・スピードを出力
float distance_x = Math.abs((event1.getX() - event2.getX()));
float velocity_x = Math.abs(velocityX);
Log.d("","横の移動距離:" + distance_x + " 横の移動スピード:" + velocity_x);

// Y軸の移動距離が大きすぎる場合
if (Math.abs(event1.getY() - event2.getY()) > SWIPE_MAX_OFF_PATH) {
Log.d("","event1.getY() - event2.getY():" + String.valueOf(event1.getY() - event2.getY()));
scrollView.smoothScrollBy(0,(int)(event1.getY() - event2.getY()));
}
// 開始位置から終了位置の移動距離が指定値より大きい
// X軸の移動速度が指定値より大きい
else if (event1.getX() - event2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Log.d("","右から左");
imageIndex += 1;
showImage(bitmap.get(imageIndex));
Log.d("","imageIndex" + imageIndex);
}
// 終了位置から開始位置の移動距離が指定値より大きい
// X軸の移動速度が指定値より大きい
else if (event2.getX() - event1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
Log.d("","左から右");
imageIndex -= 1;
showImage(bitmap.get(imageIndex));
}

} catch (Exception e) {
Log.d("",e.getMessage());
}
return false;
}
};

スクロールにはsrollView.smoothScrollByってやつ使ってますが、若干スクロールがかくついたりします。

あと指離した瞬間にスクロールされてしまいます。指の動きと同期したいんですがね。。。

なんかいい方法知っている方いたらご教示ください。