質問

gesturedetector.simpleongestureLelistenerのOnscrollメソッドを使用して、キャンバスに大きなビットマップをスクロールしています。スクロールが終了したら、ユーザーがさらにスクロールしたい場合にビットマップを再描画したいのですが...ビットマップの端から外れていますが、スクロールが終了したときに検出する方法がわかりません(ユーザーは指を上げました。画面から)。

e2.getAction()は常に値2を返しているように見えるので、それは助けになりません。 E2.GETPressureは、圧力が約0.13に低下するように見える最終的なオンスクロールコールがかなり一定の値(約0.25)を返しているようです。私はこの圧力の低下を検出できると思いますが、これは絶対確実にはほど遠いでしょう。

より良い方法がなければなりません:誰でも助けてくれませんか?

役に立ちましたか?

解決

これが私が問題を解決した方法です。お役に立てれば。

// declare class member variables
private GestureDetector mGestureDetector;
private OnTouchListener mGestureListener;
private boolean mIsScrolling = false;


public void initGestureDetection() {
        // Gesture detection
    mGestureDetector = new GestureDetector(new SimpleOnGestureListener() {
        @Override
        public boolean onDoubleTap(MotionEvent e) {
            handleDoubleTap(e);
            return true;
        }

        @Override
        public boolean onSingleTapConfirmed(MotionEvent e) {
            handleSingleTap(e);
            return true;
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // i'm only scrolling along the X axis
            mIsScrolling = true;                
            handleScroll(Math.round((e2.getX() - e1.getX())));
            return true;
        }

        @Override
        /**
         * Don't know why but we need to intercept this guy and return true so that the other gestures are handled.
         * https://code.google.com/p/android/issues/detail?id=8233
         */
        public boolean onDown(MotionEvent e) {
            Log.d("GestureDetector --> onDown");
            return true;
        }
    });

    mGestureListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {

            if (mGestureDetector.onTouchEvent(event)) {
                return true;
            }

            if(event.getAction() == MotionEvent.ACTION_UP) {
                if(mIsScrolling ) {
                    Log.d("OnTouchListener --> onTouch ACTION_UP");
                    mIsScrolling  = false;
                    handleScrollFinished();
                };
            }

            return false;
        }
    };

    // attach the OnTouchListener to the image view
    mImageView.setOnTouchListener(mGestureListener);
}

他のヒント

あなたは見てください http://developer.android.com/reference/android/widget/scroller.html。特に、これは助けになる可能性があります(関連性によってソートされます):

isFinished();
computeScrollOffset();
getFinalY(); getFinalX(); and getCurrY() getCurrX()
getDuration()

これは、スクロラーを作成する必要があることを意味します。

接触を使用する場合は、GestureDetectorを使用して、独自のキャンバススクロールを定義することもできます。次のサンプルはScrollableImageViewを作成しており、それを使用するには、画像の測定値を定義する必要があります。独自のスクロール範囲を定義することができ、スクロールを終了した後、画像は再描画されます。

http://www.anddev.org/viewtopic.php?p=31487#31487

コードに応じて、無効化を検討する必要があります(int l、int t、int r、int b)。無効化のため。

SimpleOnGestureListener.onFling() 

スクロールが終了したときに行われるようです(つまり、ユーザーが指を手放す)、それが私が使用しているものであり、私にとってはうまく機能します。

数ヶ月後にこれに戻って、私は今や別のタックを追跡しました:ハンドラー(Android Snakeサンプルのように)を使用して、125ミリ秒ごとにアプリにメッセージを送信して、スクロールが開始されたかどうかを確認するように促します最後のスクロールイベント以来、100ミリ秒以上が経過しているかどうか。

これは非常にうまく機能しているようですが、誰かが欠点や改善の可能性を見ることができれば、それらを聞いて感謝すべきです。

関連するコードはMyViewクラスにあります。

public class MyView extends android.view.View {

...

private long timeCheckInterval = 125; // milliseconds
private long scrollEndInterval = 100;
public long latestScrollEventTime;
public boolean scrollInProgress = false;

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

private timeCheckHandler mTimeCheckHandler = new timeCheckHandler();

class timeCheckHandler extends Handler{

        @Override
        public void handleMessage(Message msg) {
        long now = System.currentTimeMillis();
        if (scrollInProgress && (now>latestScrollEventTime+scrollEndInterval)) {
                    scrollInProgress = false;

//スクロールが終了したので、ここにコードを挿入してください

// dodrawing()メソッドを呼び出す

//スクロールが終了した場所で再中心にbitmapを再描画する

                    [ layout or view ].invalidate();
        }
        this.sleep(timeCheckInterval);
        }

        public void sleep(long delayMillis) {
            this.removeMessages(0);
            sendMessageDelayed(obtainMessage(0), delayMillis);
            }
    }
}

@Override protected void onDraw(Canvas canvas){
        super.onDraw(canvas);

//ビューのキャンバスに大きなバッファービットマップを描画するコード//進行中のスクロールを考慮して配置されています

}

public void doDrawing() {

//詳細な(および時間のかかる)図面を実行するコード//大型バッファービットマップに

//次の命令はタイムチェッククロックをリセットします//クロックは最初に開始されます//メインアクティビティがアプリが起動したときにこのメソッドを呼び出すとき

        mTimeCheckHandler.sleep(timeCheckInterval);
}

// MyViewクラスの残り

}

MygestureDetectorクラスで

public class MyGestureDetector extends SimpleOnGestureListener {

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
        float distanceY) {

    [MyView].scrollInProgress = true;
        long now = System.currentTimeMillis();  
    [MyView].latestScrollEventTime =now;

    [MyView].scrollX += (int) distanceX;
    [MyView].scrollY += (int) distanceY;

//次の命令により、ビューのオンドローメソッドが呼び出されます//バッファビットマップを画面にプロットします//スクロールを考慮してシフトしました

    [MyView].invalidate();

}

// mygestureDetectorクラスの残り

}

私はこの同じ問題を検討していました。 Akos CZがあなたの質問に答えているのを見ました。同様のものを作成しましたが、私のバージョンでは、通常のスクロールでのみ機能していることに気付きました。しかし、投げが生成された場合 - 私が投げ入れを処理したかどうかに関係なく、「Ontouchevent」の「Action_up」は検出されませんでした。今では、これは私の実装の単なるものでしたが、もしそうなら、その理由を理解できませんでした。

さらなる調査の後、私は飛び出し中に、「action_up」が毎回「e2」で「fling」に渡されたことに気付きました。ですから、私はそれが「Ontouchevent」で処理されていなかった理由であるに違いないと考えました。

私のためにそれを機能させるには、「Onfling」の「Action_up」を処理する方法を呼び出すだけで、両方のタイプのスクロールで機能しました。以下は、アプリに実装するために取った正確な手順です。

- コンストラクターの「ジェスチャークロール」ブール値を「false」に照合しました。

- 私はそれを「Onscroll」で「真」に設定します

- 「action_up」イベントを処理する方法を作成しました。そのイベント内では、「GestureScrolling」をFalseにリセットしてから、必要な残りの処理を行いました。

- 「ontouchevent」で、「action_up」が検出され、「gesturescrolling」= trueの場合、「action_up」を処理する方法を呼び出しました。

- そして、私がそれをした部分は異なっていました。「Onfling」内の「Action_up」を処理する方法と呼ばれました。

私はそれがあなたにとって遅すぎると確信していますが、私はあなたの元の質問に対する正しい解決策を見つけたようであり、意図は必要ではありません。

スクロールにScreoller/Overscrollerオブジェクトを使用している場合は、次の関数から戻り値を確認する必要があります。

public boolean computeScrollOffset() 

楽しい

ハービンダー

これが私のために働いたものです。

既存のものを豊かにしました GestureDetector.OngestureLelisteneronfingerup() 方法。このリスナーは、組み込みのGestureDetectorとしてすべてを行い、フィンガーアップイベントを聴くこともできます(これは、クイックスワイプアクションと一緒に指が持ち上げられた場合にのみ呼び出されます)。

import android.content.Context;
import android.os.Handler;
import android.view.GestureDetector;
import android.view.MotionEvent;

public class FingerUpGestureDetector extends GestureDetector {
    FingerUpGestureDetector.OnGestureListener fListener;
    public FingerUpGestureDetector(Context context, OnGestureListener listener) {
        super(context, listener);
        fListener = listener;
    }

    public FingerUpGestureDetector(Context context, GestureDetector.OnGestureListener listener, OnGestureListener fListener) {
        super(context, listener);
        this.fListener = fListener;
    }

    public FingerUpGestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, OnGestureListener fListener) {
        super(context, listener, handler);
        this.fListener = fListener;
    }

    public FingerUpGestureDetector(Context context, GestureDetector.OnGestureListener listener, Handler handler, boolean unused, OnGestureListener fListener) {
        super(context, listener, handler, unused);
        this.fListener = fListener;
    }

    public interface OnGestureListener extends GestureDetector.OnGestureListener {
        boolean onFingerUp(MotionEvent e);
    }

    public static class SimpleOnGestureListener extends GestureDetector.SimpleOnGestureListener implements FingerUpGestureDetector.OnGestureListener {
        @Override
        public boolean onFingerUp(MotionEvent e) {
            return false;
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (super.onTouchEvent(ev)) return true;
        if (ev.getAction() == MotionEvent.ACTION_UP) {
            return fListener.onFingerUp(ev);
        }
        return false;
    }
}

私はこれを自分で行っていませんが、ontouch()を見ると、常にシーケンス0 <2> 1を取得しているので、指を揚げるには終わりが1でなければなりません。

私はAndroidを知りませんが、ドキュメントを見るとRobは正しいようです: Android Action_up定数 getAction()からaction_upをチェックしてみませんか?

編集:e1.getAction()は何を示しますか? Action_upを返したことはありますか?ドキュメントでは、最初のダウンイベントが保持されているので、ポインターがいつ上がっているかも通知するかもしれません

編集:私が考えることができる2つのことだけ。いつでも偽りを返していますか?それはaction_upを防ぐかもしれません

私が試してみる他の唯一のことは、別のイベント、おそらくオンになり、IsscrollingなどのOnscroll内にフラグを設定することです。 Action_upがOndownに与えられ、Isscrollingが設定されると、必要なことは何でも実行し、IsscrollingをFalseにリセットできます。つまり、オンダウンがonscrollと一緒に呼び出されると仮定すると、getactionはdown中にaction_upを返します

私はこれを試した /使用していませんが、アプローチのアイデアです。

すべてのスクロールイベントでキャンバスを停止 /中断します。

これは、最後のスクロールのみが実際に再描画が完了するために途切れないため、スクロールエンドでのみ再描画を実行することにつながります。

このアイデアがあなたを助けることを願っています:)

GestureLelistener APIからのOnscrollイベントから抽出: テキストをリンクします

Public Abstract Boolean Onscroll(MotionEvent E1、MotionEvent E2、Float DistanceX、Float Distancey)以来:APIレベル1

イベントが消費されている場合、returns * true、else false

おそらく、イベントが消費されると、アクションが終了し、ユーザーが画面から指を離すか、少なくともこのOnscrollアクションを終了しました

次に、これをIFステートメントで使用して== trueをスキャンしてから次のアクションで開始できます。

これは必要に応じて機能すると思います

protected class SnappingGestureDetectorListener extends SimpleOnGestureListener{

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY){
        boolean result = super.onScroll(e1, e2, distanceX, distanceY);

        if(!result){
            //Do what you need to do when the scrolling stop here
        }

        return result;
    }

}

ジェスチャー検出器に追加の機能を追加しようとする私の試み。誰かが彼の時間をよりよく使うのに役立つことを願っています...

https://gist.github.com/wildorangutan/043807ddbd68978179b7cea3b53c71e8

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top