Scrolling in der Listenansicht deaktivieren

Ich habe eine Listenansicht und je nach Logik möchte ich das Scrollen vorübergehend deaktivieren. view.setOnScrollListener (null); hilft mir nicht Ich denke, ich muss etwas Code schreiben, kann mir jemand ein Hist oder ein Schnipsel geben?

Vielen Dank

In Ihrer CustomListView:

@Override public boolean dispatchTouchEvent(MotionEvent ev){ if(ev.getAction()==MotionEvent.ACTION_MOVE) return true; return super.dispatchTouchEvent(ev); } 

Dann reactjs ListView auf Klicks, ändert aber nicht die Bildlaufposition.

Eine andere Möglichkeit, ohne ein neues benutzerdefiniertes ListView zu erstellen, wäre, einen onTouchListener an Ihre ListView anzuhängen und true im onTouch() Callback zurückzugeben, wenn die Bewegungsereignisaktion ACTION_MOVE .

 listView.setOnTouchListener(new OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { return (event.getAction() == MotionEvent.ACTION_MOVE); } }); 

Verwenden Sie listview.setEnabled (false) , um das Scrollen mit der Listenansicht zu deaktivieren

Hinweis: Dies deaktiviert auch die Zeilenauswahl

Wenn ein Ereignis an die Listenelemente gebunden ist, triggers das Ziehen der Liste mit einer dieser Lösungen weiterhin das Ereignis aus. Sie möchten die folgende Methode verwenden, um die Erwartung der Benutzer zu berücksichtigen, das Ereignis abzubrechen, indem Sie das ausgewählte Element wegziehen (angepasst aus der Antwort von Pointer Null):

 @Override public boolean dispatchTouchEvent(MotionEvent ev) { final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK; if (actionMasked == MotionEvent.ACTION_DOWN) { // Record the position the list the touch landed on mPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); return super.dispatchTouchEvent(ev); } if (actionMasked == MotionEvent.ACTION_MOVE) { // Ignore move events return true; } if (actionMasked == MotionEvent.ACTION_UP) { // Check if we are still within the same view if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) { super.dispatchTouchEvent(ev); } else { // Clear pressed state, cancel the action setPressed(false); invalidate(); return true; } } return super.dispatchTouchEvent(ev); } 

Die vollständige class für benutzerdefinierte Ansichten ist verfügbar: https://gist.github.com/danosipov/6498490

CustomListView deine CustomListView

 @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(needToStop){ return false;} return super.onInterceptTouchEvent(ev); } 

Bei false die Kinder das Touch-Ereignis behandeln, stellen Sie sicher, dass Sie Ihre if condition , um zu überprüfen, ob Sie blättern müssen oder nicht.

Die beste Antwort für mich ist der von Dan Osipov. Ich würde es so verbessern. (Auslösen eines CANCEL-Aktionsereignisses, anstatt den gedrückten Zustand manuell zu löschen).

 @Override public boolean dispatchTouchEvent(MotionEvent ev) { final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK; if (actionMasked == MotionEvent.ACTION_DOWN) { // Record the position the list the touch landed on mPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); return super.dispatchTouchEvent(ev); } if (actionMasked == MotionEvent.ACTION_MOVE) { // Ignore move events return true; } if (actionMasked == MotionEvent.ACTION_UP) { // Check if we are still within the same view if (pointToPosition((int) ev.getX(), (int) ev.getY()) != mPosition) { // Clear pressed state, cancel the action ev.setAction(MotionEvent.ACTION_CANCEL); } } return super.dispatchTouchEvent(ev); } 

Beim Schreiben von Code zum Wischen zum Löschen in einer Listenansicht wollte ich das vertikale Scrollen verhindern, sobald der Wischvorgang erkannt wurde. Ich habe ein boolesches Flag im ACTION_MOVE-Bereich gesetzt, sobald die Swipe-Bedingungen zum Löschen erfüllt waren. Die Methode dispatchTouchEvent überprüft diese Bedingung und verhindert, dass der Bildlauf funktioniert. In der ACTION_UP setze ich das Flag zurück auf false, um den Scroll wieder zu aktivieren.

 private float mY = Float.NaN; private boolean mStopScroll = false; @Override public boolean onTouch(View view, MotionEvent event) { if(!mStopScroll) { mY = event.getY(); } switch (event.getAction()) { case MotionEvent.ACTION_MOVE: if() { mStopScroll = true; } break; case MotionEvent.ACTION_UP: mStopScroll = false; // your code here return true; default: } return false; } @Override public boolean dispatchTouchEvent(MotionEvent motionEvent) { if(mStopScroll) { motionEvent.setLocation(motionEvent.getX(), mY); } return super.dispatchTouchEvent(motionEvent); } 

Meine Antwort wird für Xamarin- und MvvmCross-Benutzer interessant sein. Das Hauptkonzept ist das gleiche wie in den vorherigen Beiträgen, daher sind die wichtigsten Schritte:

  1. Stumm Scroll-Ereignisse
  2. Ändern Sie dynamisch die Listenhöhe

Hier sind Sie Helfer class, die Scroll in der Listenansicht deaktivieren können:

 using System; using Cirrious.MvvmCross.Binding.Droid.Views; using Android.Content; using Android.Util; using Android.Views; using Android.Database; namespace MyProject.Android.Helpers { public class UnscrollableMvxListView : MvxListView { private MyObserver _myObserver; public UnscrollableMvxListView (Context context, IAttributeSet attrs, MvxAdapter adapter) : base(context, attrs, adapter) { } protected override void OnAttachedToWindow () { base.OnAttachedToWindow (); var dtso = new MyObserver(this); _myObserver = dtso; Adapter.RegisterDataSetObserver (dtso); } protected override void OnDetachedFromWindow () { Log.Debug ("UnscrollableMvxListView", "OnDetachedFromWindow"); if (_myObserver != null) { Adapter.UnregisterDataSetObserver (_myObserver); _myObserver = null; } base.OnDetachedFromWindow (); } //Make List Unscrollable private int _position; public override bool DispatchTouchEvent (MotionEvent ev) { MotionEventActions actionMasked = ev.ActionMasked & MotionEventActions.Mask; if (actionMasked == MotionEventActions.Down) { // Record the position the list the touch landed on _position = PointToPosition((int) ev.GetX (), (int) ev.GetY()); return base.DispatchTouchEvent(ev); } if (actionMasked == MotionEventActions.Move) { // Ignore move events return true; } if (actionMasked == MotionEventActions.Up) { // Check if we are still within the same view if (PointToPosition((int) ev.GetX(), (int) ev.GetY()) == _position) { base.DispatchTouchEvent(ev); } else { // Clear pressed state, cancel the action Pressed = false; Invalidate(); return true; } } return base.DispatchTouchEvent(ev); } //Make List Flat public void JustifyListViewHeightBasedOnChildren () { if (Adapter == null) { return; } var vg = this as ViewGroup; int totalHeight = 0; for (int i = 0; i < Adapter.Count; i++) { View listItem = Adapter.GetView(i, null, vg); listItem.Measure(0, 0); totalHeight += listItem.MeasuredHeight; } ViewGroup.LayoutParams par = LayoutParameters; par.Height = totalHeight + (DividerHeight * (Adapter.Count - 1)); LayoutParameters = par; RequestLayout(); } } internal class MyObserver : DataSetObserver { private readonly UnscrollableMvxListView _unscrollableMvxListView; public MyObserver (UnscrollableMvxListView lst) { _unscrollableMvxListView = lst; } public override void OnChanged() { Log.Debug("UnscrollableMvxListView", "OnChanged"); base.OnChanged (); _unscrollableMvxListView.JustifyListViewHeightBasedOnChildren (); } } } 

Dies ist der Code Joe Blow (Kommentar zu OP-Post), der auf http://danosipov.com/?p=604 gezeigt wurde, aber ich poste es hier, um es zu erhalten, falls der Link verwaist ist:

 public class ScrollDisabledListView extends ListView { private int mPosition; public ScrollDisabledListView(Context context) { super(context); } public ScrollDisabledListView(Context context, AttributeSet attrs) { super(context, attrs); } public ScrollDisabledListView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { final int actionMasked = ev.getActionMasked() & MotionEvent.ACTION_MASK; if (actionMasked == MotionEvent.ACTION_DOWN) { // Record the position the list the touch landed on mPosition = pointToPosition((int) ev.getX(), (int) ev.getY()); return super.dispatchTouchEvent(ev); } if (actionMasked == MotionEvent.ACTION_MOVE) { // Ignore move events return true; } if (actionMasked == MotionEvent.ACTION_UP) { // Check if we are still within the same view if (pointToPosition((int) ev.getX(), (int) ev.getY()) == mPosition) { super.dispatchTouchEvent(ev); } else { // Clear pressed state, cancel the action setPressed(false); invalidate(); return true; } } return super.dispatchTouchEvent(ev); } } 

Wenn Sie dieses ListView zu Ihrem Layout hinzufügen, denken Sie daran, es mit seinem Paketnamen zu beginnen, andernfalls wird eine Ausnahme ausgetriggers, wenn Sie versuchen, es aufzublasen.

Versuche dies:

 listViewObject.setTranscriptMode(0); 

functioniert bei mir.