Intereting Posts
Разработайте приложение для Android с помощью C # Импорт android.support не может быть разрешен Android GLSurfaceView вызывает утечку? Почему добавление локальных переменных вызывает задержку в методе? Определить, есть ли у контакта фотография Как играть в видео как живые обои android? Показать вверх / назад на Android-экране с установленными предпочтениями? Отправить электронную почту программно в Android Объявление активности в AndroidManifest.xml Установить подсказку поиска динамически Изменение размера поискового ключа программно, но не может заставить большой палец быть больше, чем панель Почему nextFocusDown не работает с навигацией TalkBack? Лямбда-выражения разбиваются с помощью IncompatibleClassChangeError в Android при использовании разъема Отсутствует adActivity с android: configChanges в AndroidManifest.xml «MinifyEnabled» против «shrinkResources» – какая разница? И как получить сохраненное пространство?

Android: как обнаружить, когда свиток закончился

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

E2.getAction () всегда, кажется, возвращает значение 2, поэтому это не поможет. E2.getPressure, кажется, возвращает довольно постоянные значения (около 0,25) до тех пор, пока окончательный вызов Sscroll, когда давление, похоже, упадет примерно до 0,13. Полагаю, я мог бы обнаружить это снижение давления, но это будет далеко не надежным.

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

Solutions Collecting From Web of "Android: как обнаружить, когда свиток закончился"

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

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

В зависимости от вашего кода вы должны рассмотреть invalidate (int l, int t, int r, int b); За недействительность.

Возвращаясь к этому через несколько месяцев, я теперь придерживался другого подхода: используя обработчик (как в примере Android Snake), чтобы отправить сообщение в приложение каждые 125 миллисекунд, что побуждает его проверить, был ли запущен Scroll и Прошло ли более 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

}

И в классе 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; 

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

  [MyView].invalidate(); } 

// остаток класса MyGestureDetector

}

 SimpleOnGestureListener.onFling() 

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

Я изучал эту же проблему. Я видел, как Акос Чж ответил на ваш вопрос. Я создал что-то подобное, но с моей версией я заметил, что он работал только для обычного прокрутки, а это значит, что он не генерирует бросок. Но если бросок действительно сгенерировался – независимо от того, обработал ли я или нет, тогда он НЕ обнаружил «ACTION_UP» в «onTouchEvent». Теперь, возможно, это было что-то с моей реализацией, но если бы это было, я не мог понять, почему.

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

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

-инициализировал «gestureScrolling» логическое значение «false» в конструкторе.

-Я установил его «true» в «onScroll»

-создал метод обработки события «ACTION_UP». Внутри этого события я сбросил «gestureCrolling» на false, а затем выполнил всю оставшуюся обработку, которую мне нужно было сделать.

-в «onTouchEvent», если обнаружено «ACTION_UP» и «gestureScrolling» = true, то я вызвал свой метод для обработки «ACTION_UP»

-И часть, которую я сделал, была другая: я также назвал мой метод обработкой «ACTION_UP» внутри «onFling».

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

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

 public boolean computeScrollOffset() 

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

harvinder

Я не сделал этого сам, но, глядя на onTouch (), вы всегда получаете последовательность 0 <2> 1, поэтому конец должен быть 1 для подъема пальца.

Я не знаю Android, но, глядя на документацию, кажется, что Роб прав: Android ACTION_UP constant Попробуйте проверить ACTION_UP из getAction ()?

Изменить: что показывает e1.getAction ()? Возвращает ли он ACTION_UP? В документации говорится, что он содержит начальное событие down, поэтому, возможно, оно также сообщит, когда указатель поднят

Редактировать: Только две вещи, о которых я могу думать. Вы возвращаетесь в любой момент? Это может предотвратить ACTION_UP

Единственное, что я попробую, это иметь отдельное событие, возможно onDown, и установить флаг внутри onScroll, такой как isScrolling. Когда ACTION_UP присваивается значение onDown и isScrolling установлен, вы можете делать все, что хотите, и сбросить isScrolling в false. То есть, предполагая, что onDown вызывается вместе с onScroll, и getAction вернет ACTION_UP во время onDown

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

Остановить / прервать перерисовку холста на КАЖДОМ событии прокрутки ждать 1 с, а затем начать перерисовывать холст на КАЖДОЙ прокрутке.

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

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

Выдержка из события onScroll из API GestureListener: текст ссылки

Public abstract boolean onScroll (MotionEvent e1, MotionEvent e2, float distanceX, плавающая дистанцияY) Начиная с: API уровня 1

Возвращает * true, если событие потребляется, иначе 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; } } 

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

Я обогатил существующий GestureDetector.OnGestureListener с помощью метода onFingerUp () . Этот слушатель делает все как встроенный GestureDetector, и он также может прослушивать событие finger up (это не 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; } }