ProblemVerhindern RecyclerView von Touch-Ereignisse raubend
ich das genaue Verhalten der Google Play-Funktion zu simulieren versucht bin.
Derzeit, wenn Sie durch eine Kategorie wie 'Top Games' blättern und Sie die Liste berühren, die Zelle sowie die RecyclerView
behandelt das Touch-Ereignis, können Sie beide sie behandeln aufgrund der Ripple erscheinen wann Sie halten den Finger gedrückt und das Scrollen kommt zum Stillstand. Oder wenn Sie auf eine Zelle klicken, während sich die Liste noch bewegt, wird der Inhalt sofort geöffnet.
Das voreingestellte Verhalten ist, dass das Scrollen sofort stoppt, wenn Sie den Finger während der Bewegung ablegen und dann dieses Berührungsereignis konsumieren, was bedeutet, dass die Zelle niemals über diese Berührung informiert wird. Das ist unglaublich irritierend, wenn sich der Hauptinhalt Ihrer Anwendung in einer RecyclerView
befindet. Wenn der Benutzer ständig scrollt und dann auf eine Zelle klickt, müssen diese zwei Mal klicken, da der erste Klick durch das Anhalten der Bildlaufleiste verbraucht wurde, selbst wenn die Liste war kaum bewegt.
, was ich bisher
Zuerst versucht haben, dachte ich, es irgendeine Art von Flagge innerhalb der RecyclerView
sein muß, die es den Touch-Ereignis nicht zu konsumieren erzählt. Ich habe den Android-Quellcode durchgesehen und die Android-Dokumentation ohne Erfolg durchgelaufen.
Dann habe ich versucht, das Berührungsereignis mit onInterceptTouchEvent
zu erfassen und meine Ansicht manuell zu erzählen, dass es berührt wird;
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
View myCell = recyclerView.findChildViewUnder(event.getX(), event.getY());
myCell.dispatchTouchEvent(event);
return super.onInterceptTouchEvent(event);
}
Hier dispatchTouchEvent
scheinen nichts zu tun, auch wenn die Aussicht Ich war immer der entsprechende Tag gehabt, die ich in den Adapter gesetzt.
Ich habe versucht, dieses Problem mit meinem Code Maschinengewehr in allen Winkeln zu schießen; Spielen mit requestDisallowInterceptTouchEvent
, manuell aufrufen onTouch
und überschreiben alle Arten von Listenern für die RecyclerView
und darüber hinaus.
Nichts scheint zu funktionieren. Ich bin mir sicher, dass es eine elegante Lösung dafür geben muss und ich habe irgendwo auf dem Weg zum Wahnsinn ein wichtiges Detail überflogen. Vor allem, weil sich Google-eigene Apps auf diese Weise verhalten.
Bitte helfen! :) Vielen Dank.
Die Lösung
Dank Jagoan Neon eine Lösung gefunden wurde. Ich beendete seine Antwort in einem benutzerdefinierten RecyclerView
für die Benutzerfreundlichkeit.
public class MultiClickRecyclerView extends RecyclerView {
public MultiClickRecyclerView(Context context) {
super(context);
}
public MultiClickRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MultiClickRecyclerView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN && this.getScrollState() == RecyclerView.SCROLL_STATE_SETTLING) {
this.stopScroll();
}
return super.onInterceptTouchEvent(event);
}
}
Ich implementierte Ihre Antwort heute Morgen und wir sind fast da! Es ist komisch; Diese Lösung scheint ungefähr 30% der Zeit zu funktionieren, abhängig davon, wie langsam ich vorher ziehe. Ich habe das Bewegungsereignis und den Bildlaufstatus abgemeldet und es scheint keinen Unterschied zu geben, wann es funktioniert und wann nicht. Wenn ich schnell durch die Liste scrolle und dann auf den Finger tippe und halte, registriert sie fast nie den Touch und zeigt die Welligkeit an (wie die Google Play App). Funktioniert es ständig für dich? Ich benutze ein Grid-Layout mit zwei Spannen, obwohl ich mir nicht vorstellen würde, dass dies einen Unterschied machen würde. – vguzzi
Hast du meine zweite Bearbeitung gesehen? –
Ja, ich bin gerade auf der Stop Scroll View Implementierung. Ich habe auch die vorherigen Vorschläge ausprobiert. – vguzzi