Позвольте родительскому представлению принять MotionEvents, если child возвращает false - PullRequest
3 голосов
/ 06 сентября 2011

У меня есть приложение, которое требует необычной обработки событий.

Для моего вопроса позвольте мне сначала объяснить простой случай, когда текущая система обработки событий Android не подходит для меня.

Предполагая, что у меня есть FrameLayout (с этого момента я буду называть ViewSwiper), все добавленные в него представления - это MATCH_PARENT X MATCH_PARENT (который я буду называть PageView), он обрабатывает события, переводя фактический вид View и заменяя его.в зависимости от направления движения.Этот компонент я уже выполнил и работаю правильно ( Использование анимации для смахивания видов ).

Но проблема в том, что PageView я добавляю поверх него, в случае ImageViews, которые возвращают falseв onTouchEvent ViewSwiper будет обрабатывать события и позволять другому PageView выходить на экран, но если я добавлю ScrollView для этого, все события будут использованы Scroll, и ViewSwiper не сможет заменить PageView.

Итак, я выяснил, что при возвращении false onTouchEvent объекта ScrollView родитель может предполагать его события, я написал этот подкласс 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 только в том случае, если пользователь перемещает HORIZONTAL, так выглядит мой код:

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 вернет true на track () после некоторых событий и сообщит, в каком направлении находится пользовательПеремещение.

Но в этом случае ScrollView продолжает получать события, так как он возвращает true при первых событиях.

Любые идеи о том, как я могу обработать события в ViewSwiper, когда его дочерний элемент возвращает false (даже если верны некоторые истины).

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

Все равно ничего.

Ответы [ 2 ]

3 голосов
/ 06 сентября 2011

попробуйте это в 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;

Обновление

Пожалуйста, попробуйте следующее для пользовательского прокрутки

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

И ничего больше

Таким образом, я предполагаю, что MotionEvent будет работать на обоих видах.И поскольку они не конфликтуют (один вертикальный, другой горизонтальный), это может сработать

1 голос
/ 08 сентября 2011

Исходя из ответа от слабого провода, я пришел к следующему решению:

На ViewSwiper

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

И на ScrollHorizontal Я возвращаю false на dispatchTouchEvent, когда мне больше не нужно.

...