Ich musste kürzlich die von Ihnen beschriebene Funktion implementieren. Was ich getan habe, war eine Runnable-Überprüfung, ob die ScrollView aufgehört hat zu scrollen, indem der von getScrollY () zurückgegebene Wert verglichen wurde, als das onTouchEvent zum ersten Mal mit dem Wert ausgelöst wurde, der nach einer durch die Variable newCheck definierten Zeit zurückgegeben wurde .
Siehe Code unten (Arbeitslösung):
public class MyScrollView extends ScrollView{
private Runnable scrollerTask;
private int initialPosition;
private int newCheck = 100;
private static final String TAG = "MyScrollView";
public interface OnScrollStoppedListener{
void onScrollStopped();
}
private OnScrollStoppedListener onScrollStoppedListener;
public MyScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
scrollerTask = new Runnable() {
public void run() {
int newPosition = getScrollY();
if(initialPosition - newPosition == 0){//has stopped
if(onScrollStoppedListener!=null){
onScrollStoppedListener.onScrollStopped();
}
}else{
initialPosition = getScrollY();
MyScrollView.this.postDelayed(scrollerTask, newCheck);
}
}
};
}
public void setOnScrollStoppedListener(MyScrollView.OnScrollStoppedListener listener){
onScrollStoppedListener = listener;
}
public void startScrollerTask(){
initialPosition = getScrollY();
MyScrollView.this.postDelayed(scrollerTask, newCheck);
}
}
Dann habe ich:
scroll.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
scroll.startScrollerTask();
}
return false;
}
});
scroll.setOnScrollStoppedListener(new OnScrollStoppedListener() {
public void onScrollStopped() {
Log.i(TAG, "stopped");
}
});
Übrigens habe ich einige Ideen aus anderen Antworten verwendet, um dies in meiner App zu tun. Hoffe das hilft. Fragen können Sie gerne stellen. Prost.
Hier ist noch eine weitere Lösung für den IMHO fehlenden OnEndScroll-Ereignisfehler in der ScrollView.
Es ist inspiriert von hambonious Antwort. Fügen Sie diese Klasse einfach in Ihr Projekt ein (ändern Sie das Paket entsprechend Ihrem eigenen) und verwenden Sie die folgende XML-Datei
Ändern Sie den Paketnamen erneut entsprechend Ihrem Projekt
quelle
2
auf0.5f
das Original zu reflektierenScrollView
‚s -MAX_SCROLL_FACTOR
Wert.Ich habe (horizontal) ScrollView untergeordnet und so etwas gemacht:
Ich habe den Wert 1 für den SlowDownThreshold verwendet, da dies immer der Unterschied zum letzten onScrollChanged-Ereignis zu sein scheint.
Damit sich dies beim langsamen Ziehen richtig verhält, musste ich Folgendes tun:
quelle
Mein Ansatz besteht darin, den Bildlaufstatus durch einen Zeitstempel zu bestimmen, der bei jedem Aufruf von onScrollChanged () geändert wird. Es ist sehr einfach festzustellen, wann der Bildlauf beginnt und endet. Sie können auch den Schwellenwert ändern (ich verwende 100 ms), um die Empfindlichkeit zu korrigieren.
quelle
Hier ist noch eine andere Lösung, die meiner Meinung nach recht einfach und sauber ist und natürlich von den obigen Antworten inspiriert wurde. Wenn der Benutzer die Geste beendet hat, prüfen Sie nach einer kurzen Verzögerung (hier 50 ms), ob sich getScrollY () noch ändert.
quelle
Mein Ansatz für diese Frage besteht darin, einen Timer zu verwenden, um nach den folgenden 2 "Ereignissen" zu suchen.
1) onScrollChanged () wurde nicht mehr aufgerufen
2) Der Finger des Benutzers wird aus der Bildlaufansicht angehoben
quelle
Schauen Sie sich diese Frage hier auf StackOverflow an - sie entspricht nicht genau Ihrer Frage, gibt jedoch eine Vorstellung davon, wie Sie das Bildlaufereignis von a verwalten können
ScrollView
.Grundsätzlich müssen Sie Ihre eigenen erstellen,
CustomScrollView
indem Sie sie erweiternScrollView
und überschreibenonScrollChanged(int x, int y, int oldx, int oldy)
. Dann müssen Sie dies in Ihrer Layout-Datei anstelle des Standard-ScrollView
Like referenzierencom.mypackage.CustomScrollView
.quelle
Für einen einfachen Fall, wie Sie ihn beschrieben haben, können Sie wahrscheinlich mit der überschreibenden Schleudermethode in Ihrer benutzerdefinierten Bildlaufansicht davonkommen. Die Fling-Methode wird aufgerufen, um jedes Mal, wenn der Benutzer seinen Finger vom Bildschirm hebt, eine "Verzögerung" durchzuführen.
Was Sie also tun sollten, ist ungefähr so:
Unterklasse ScrollView.
Subclass-Fling-Methode und NICHT Superclass-Implementierung aufrufen.
Fling wird nicht ausgelöst, wenn der Benutzer aufhört zu scrollen, bevor er seinen Finger hebt (Geschwindigkeit Y == 0). Wenn Sie diese Art von Ereignissen ebenfalls abfangen möchten, überschreiben Sie onTouchEvent.
HINWEIS Obwohl dies funktioniert, ist es möglicherweise eine schlechte Idee, die Schleudermethode zu überschreiben. Es ist öffentlich, aber kaum für Unterklassen konzipiert. Im Moment macht es 3 Dinge - es initiiert das Fling für privaten mScroller, behandelt mögliche Fokusänderungen und zeigt Bildlaufleisten an. Dies könnte sich in zukünftigen Android-Versionen ändern. Beispielsweise hat die private mScroller-Instanz ihre Klasse zwischen 2.3 und 3.0 von Scroller in OvershootScroller geändert. Sie müssen all diese kleinen Unterschiede berücksichtigen. Seien Sie auf jeden Fall bereit für unvorhergesehene Folgen in der Zukunft.
quelle
Hier ist meine Lösung, die Scroll-Tracking und Scroll-Ending umfasst:
quelle
Ich denke, das ist in der Vergangenheit aufgetaucht. AFAIK, das kann man nicht leicht erkennen. Mein Vorschlag ist, dass Sie einen Blick darauf werfen
ScrollView.java
(so machen wir die Dinge in Android Land :)) und herausfinden, wie Sie die Klasse erweitern können, um die Funktionalität bereitzustellen, die Sie suchen. Folgendes würde ich zuerst versuchen:quelle
onScrollChanged
,scrollTo
oder jedes anderes Scroll-verwandtes Verfahren. Alternativ können Sie einfach den gesamtenScrollView
Code kopieren und dieses Feld erstellenprotected
. Das würde ich allerdings nicht empfehlen.Meine Lösung ist eine Variation der großartigen Lösung von Lin Yu Cheng und erkennt auch, wann das Scrollen gestartet und gestoppt wurde.
Schritt 1. Definieren Sie eine HorizontalScrollView und einen OnScrollChangedListener:
Schritt 2. Fügen Sie die CustomHorizontalScrollView-Klasse hinzu:
quelle
Dies ist ein alter Thread, aber ich möchte eine kürzere Lösung hinzufügen, die ich mir ausgedacht habe:
Natürlich gibt es eine Verzögerung von 1000 Millisekunden. Passen Sie das an, wenn Sie müssen.
quelle
Ich habe die Antwort von ZeroG verbessert. Hauptsächlich das Abbrechen überschüssiger Aufgabenaufrufe und das Implementieren des Ganzen als privater OnTouchListener, sodass sich der gesamte Bildlauferkennungscode an einem Ort befindet.
Fügen Sie den folgenden Code in Ihre eigene ScrollView-Implementierung ein:
Und dann in Ihrer ScrollView-Implementierung:
quelle
Hier gibt es einige gute Antworten, aber mein Code kann erkennen, wenn das Scrollen stoppt, ohne die ScrollView-Klasse erweitern zu müssen. Jede Ansichtsinstanz kann getViewTreeObserver () aufrufen. Wenn Sie diese Instanz von ViewTreeObserver halten, können Sie mit der Funktion addOnScrollChangedListener () einen OnScrollChangedListener hinzufügen.
deklarieren Sie Folgendes:
und in Ihrem onCreate (oder einem anderen Ort) hinzufügen:
Möglicherweise möchten Sie zwischen diesen Überprüfungen eine längere oder langsamere Zeit benötigen, aber beim Scrollen wird dieser Listener sehr schnell aufgerufen, sodass er sehr schnell funktioniert.
quelle
Hoffe das Snippet hilft :)
quelle