Вопрос

Я использую метод GestureDetector. Scroll. Когда свиток закончится, я хочу перерисовать растровую карту, если пользователь захочет прокрутить дальше ... с края растрового изображения, но я не вижу, как обнаружить, когда прокрутка закончилась (пользователь поднял пальцем с экрана).

e2.getAction () всегда возвращает значение 2, так что это не помощь. E2.GetPressure, по -видимому, возвращает довольно постоянные значения (около 0,25) до окончательного вызова onscroll, когда давление, кажется, не упадет до 0,13. Я полагаю, что смогу обнаружить это снижение давления, но это будет далеко не надежно.

Должно быть лучший способ: кто -нибудь может помочь, пожалуйста?

Это было полезно?

Решение

Вот как я решил проблему. Надеюсь это поможет.

// 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()

Это подразумевает, что вы должны создать Scroller.

Если вы хотите использовать Touching, вы также можете использовать GesturedEtector и определить свой собственный прокрутка Canvas. Следующий образец - создание прокрутки, чтобы использовать его, вы должны определить измерения вашего изображения. Вы можете определить свой собственный диапазон прокрутки, и после завершения прокрутки изображение становится перерисованным.

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 ()

// перерисовать растровое изображение повторно, где прокрутка закончилась

                    [ 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

}

и в классе MygestureTect

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;

// Следующая инструкция приводит к названию метода OnDraw представления //, который застегивает буферную растровую карту на экран // сместился, чтобы учитывать свиток

    [MyView].invalidate();

}

// остальная часть класса MyStureDector

}

Я изучал эту же проблему. Я видел, как Akos CZ ответил на ваш вопрос. Я создал что -то подобное, но с моей версией я заметил, что это работало только для обычного свитка, что означает, что не генерирует бросок. Но если фринг действительно был сгенерирован - независимо от того, обработал ли я бросок или нет, то он не обнаружил «action_up» в «ontouchevent». Теперь, может быть, это было просто что -то с моей реализацией, но если бы это было, я не мог понять, почему.

После дальнейшего расследования я заметил, что во время броска «action_up» проводился в «Onfling» в «E2» каждый раз. Поэтому я подумал, что это должно быть, почему в этих случаях с ним не было обработано.

Чтобы заставить его работать для меня, мне нужно было только вызвать метод для обработки «action_up» в «Onfling», а затем он работал для обоих типов прокрутки. Ниже приведены точные шаги, которые я предпринял для реализации в своем приложении:

-ИНИТИЗАЦИИ «Гестаризирующего» ловушки с «ложным» в конструкторе.

-Я установил его на "истин" в "onscroll"

-Спять метод для обработки события "action_up". Внутри этого события я сбрасываю «жестировку» в False, а затем сделал остальную часть обработки, которую мне нужно было сделать.

-in "ontouchevent", если был обнаружен "action_up" и "жесты прокрутки" = true, то я позвонил своему методу для обработки "action_up"

-И часть, которую я сделал, была другой, была: я также позвонил своему методу, чтобы справиться с "action_up" внутри "Onfling".

Я уверен, что для вас уже слишком поздно, однако, кажется, я нашел правильное решение вашего первоначального вопроса и не нужен намерение.

Если вы используете объект Scroller/Oupproller для прокрутки, вы должны проверить возвратное значение из следующей функции.

public boolean computeScrollOffset() 

наслаждаться

Грубинт

Это то, что сработало для меня.

Я обогатил существующее GesturedEtector.ongestureListener с Onfingerup () метод Этот слушатель делает все, как встроенный жестер, и он также может выслушать событие пальца (это не OnFling (), так как это называется только тогда, когда палец поднимается вместе с быстрым действием промахивания).

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, но, глядя на документацию, кажется, Роб прав: Android Action_UP Constant Попробуйте проверить на Action_up от getAction ()?

РЕДАКТИРОВАТЬ: Что показывает e1.getAction ()? Это когда -нибудь возвращает action_up? В документации говорится, что у него есть начальное событие вниз, поэтому, возможно, она также уведомит, когда указатель выйдет

РЕДАКТИРОВАТЬ: только еще две вещи, о которых я могу подумать. Вы возвращаетесь ложным в любой момент? Это может помешать action_up

Единственное, что я попробую, - это провести отдельное событие, может быть, в дальнейшем и установить флаг в Onscroll, такой как Isscolling. Когда action_up предоставляется Ondown, и выкроется Isscolling, вы можете сделать все, что хотите, и сбросить Isscolling в False. То есть предполагая, что Ondown вызван вместе с Onscroll, и Getaction вернет action_up во время Ondown

Я не пробовал / использовал это, но идея для подхода:

Остановите / прерывайте перерывы на холсте на каждом событии прокрутки, ожидайте 1s, а затем начните перекрасить холст на каждом свитке.

Это приведет к выполнению перерисовки только на конце Scroll, так как только последний свиток фактически непрерывно будет непрерывно для завершения RedRar.

Надеюсь, эта идея поможет вам :)

Извлечение из события Onscroll из GestureListener API: ссылка текст

Общественный абстрактный логический взрыв (MotionEvent E1, MotionEvent E2, Float Distancex, Float Distance) С: уровня API 1

Возвращает * true, если событие потребляется, иначе неверно

Возможно, как только событие будет использовано, действие завершено, и пользователь снял пальцем с экрана или, по крайней мере, завершил это действие по прокрутке

Затем вы можете использовать это в операторе 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