3

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

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

追加されたすべてのビューがMATCH_PARENTXMATCH_PARENT(PageViewと呼びます)であるFrameLayout(これからViewSwiperと呼びます)があるとすると、実際のビューを変換して方向に基づいて置き換えることでイベントを処理します。移動の。このコンポーネントはすでに実行しており、正しく機能しています(アニメーションを使用してビューをスワイプします)。

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

そこで、親がScrollViewのfalse onTouchEventを返すと、それがイベントであると見なすことができることがわかりました。これをテストするために、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を返すと、親にディスパッチされるイベントがさらに作成されますが、垂直スクロールにはこれらのイベントが必要なので、ユーザーがHORIZONTALを移動している場合にのみ、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);
    }
}

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

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

子がfalseを返したときにViewSwiperでイベントを処理する方法に関するアイデア(いくつかのtrueが返された場合でも)。

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

答えに基づいて、私は次のことを試みました:

@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;
}

まだ何もありません。

4

2 に答える 2

3

onTouchEvent()スクロールビューでこれを試してください

     //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;

アップデート

カスタムScrollviewに以下を試してください

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

何もありません

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

于 2011-09-06T18:53:35.657 に答える
1

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

ViewSwiperについて

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

そして、ScrollHorizo​​ntalでは、dispatchTouchEventが不要になったときにfalseを返します。

于 2011-09-08T15:02:10.913 に答える