質問

通常とは異なる方法でイベント処理を必要とするアプリケーションがあります。

私の質問として、まず Android の現在のイベント処理システムが私に合わない簡単なケースを説明しましょう。

FrameLayout (以降 ViewSwiper と呼びます) があり、そこに追加されたすべての View が MATCH_PARENT X MATCH_PARENT (PageView と呼びます) であると仮定すると、実際の View を変換し、方向に基づいて置き換えることによってイベントを処理します。移動の。このコンポーネントはすでに実行済みで、適切に動作します( アニメーションを使用してビューをスワイプする ).

しかし、問題はその上に追加した PageView にあります。onTouchEvent で false を返す ImageView の場合、ViewSwiper がイベントを処理し、別の PageView が画面に入るようになりますが、それに ScrollView を追加すると、すべてのイベントは Scroll によって消費され、ViewSwiper が PageView を置き換える機会はありません。

そこで、ScrollView の onTouchEvent が false を返すと、親はそれがイベントであるとみなせることがわかり、それをテストするために ScrollView の次のサブクラスを作成しました。

public class ScrollViewVertical extends ScrollView {
    public ScrollViewVertical(Context context) {
        super(context);
        setOverScrollMode(OVER_SCROLL_ALWAYS);
        setVerticalScrollBarEnabled(false);
    }

    public boolean onTouchEvent(MotionEvent evt) {
        super.onTouchEvent(evt);
        return false;
    }
}

ただし、 false を返すと、さらにイベントが親にディスパッチされますが、これらのイベントは垂直スクロールに必要なので、ユーザーが水平に移動している場合にのみ false を返すという考えがあります。それが私のコードのようになります。

public class ScrollViewVertical extends ScrollView {
    private MovementTracker moveTracker;
    public ScrollViewVertical(Context context) {
        super(context);
        setOverScrollMode(OVER_SCROLL_ALWAYS);
        setVerticalScrollBarEnabled(false);
        moveTracker = new MovementTracker();
    }
    public boolean onTouchEvent(MotionEvent evt) {
        if (moveTracker.track(evt))
            if (moveTracker.getDirection() == Direction.HORIZONTAL)
                return false;

        return super.onTouchEvent(evt);
    }
}

追伸:MovementTracker は、いくつかのイベントの後に track() で true を返し、ユーザーがどの方向に移動しているかを伝えます。

ただし、その場合、ScrollView は最初のイベントで true を返すため、イベントを受信し続けます。

ViewSwiper の子が false を返した場合 (一部の true が返された場合でも)、ViewSwiper でイベントを処理する方法についてのアイデアはありますか。

追伸:必要に応じて、これについてさらに詳しい情報を提供し、別の解決策も受け入れることができます。

回答に基づいて、次のことを試しました。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    onTouchEvent(ev);
    return intercept;
}

public boolean onTouchEvent(MotionEvent evt) {
    boolean x = super.onTouchEvent(evt);

    if (moveTracker.track(evt)) {
        intercept = moveTracker.getDirection() != Direction.VERTICAL;
        if (!intercept)
            getParent().requestDisallowInterceptTouchEvent(false);
    }

    return x;
}

まだ何もありません。

役に立ちましたか?

解決

これを試してみてください onTouchEvent() ScrollViewの

     //if (evt.getAction() == MotionEvent.ACTION_MOVE) {
    if (moveTracker.track(evt)){
       if (moveTracker.getDirection() == Direction.VERTICAL){
          //Or the direction you want the scrollview keep moving
          getParent().requestDisallowInterceptTouchEvent(true);

            }
        } 
 return true;

アップデート

Custom ScrollViewに以下を試してください

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
super.dispatchTouchEvent(ev);
    return false;
}

何もありません

このようにして、MotionEventが両方のビューで実行されると仮定します。そして、彼らは競合しないので(一方は垂直であるため、もう1つは水平です)これは機能する可能性があります

他のヒント

weakwire からの回答に基づいて、次の解決策にたどり着きました。

ViewSwiper で

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if(!super.dispatchTouchEvent(ev))
            onTouchEvent(ev);
        return true;
    }

そして、Scrollhorizo​​ntal では、もう必要ない場合は、dispatchTouchEvent で false を返します。

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