Intereting Posts

Отключить прокрутку в списке

У меня есть представление списка, и в зависимости от некоторой логики я хочу временно отключить прокрутку. view.setOnScrollListener (нуль); Не помогает мне, я думаю, мне нужно написать какой-то код, может кто-нибудь дать мне историю или какой-нибудь фрагмент?

благодаря

Solutions Collecting From Web of "Отключить прокрутку в списке"

В вашем CustomListView:

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

Затем ListView будет реагировать на клики, но не будет изменять положение прокрутки.

Другим вариантом без создания нового пользовательского ListView было бы привязать onTouchListener к вашему ListView и вернуть true в onTouch() если действие события движения – ACTION_MOVE .

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

Используйте listview.setEnabled (false), чтобы отключить прокрутку списка

Примечание. Это также отключает выбор строк

Если у вас есть событие, связанное с элементами списка, перетаскивание списка с любым из этих решений по-прежнему вызовет событие. Вы хотите использовать следующий метод для учета ожиданий пользователей, чтобы отменить событие, перетащив его из выбранного элемента (адаптированный из ответа 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); } 

Доступен полный пользовательский класс просмотра: https://gist.github.com/danosipov/6498490

Сделайте свой CustomListView

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

На false дети будут обрабатывать событие касания, убедитесь, что вы положили if condition чтобы проверить, что вам нужно прокручивать или нет.

Лучший ответ для меня – это один из Дана Осипова. Я бы это улучшил. (Активирование события действия CANCEL вместо ручного стирания нажатого состояния).

 @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); } 

При написании кода для удаления из списка в виде списка я хотел предотвратить вертикальную прокрутку после обнаружения салфетки. Я установил логический флаг в секции ACTION_MOVE после того, как были выполнены пробелы для удаления условий. Метод dispatchTouchEvent проверяет это условие и препятствует работе прокрутки. В ACTION_UP я вернул флаг в значение false, чтобы снова включить прокрутку.

 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(<condition that stops the vertical scroll>) { 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); } 

Мой ответ будет интересен пользователям Xamarin и MvvmCross. Основная концепция такая же, как и в предыдущих сообщениях, поэтому основными шагами являются:

  1. Отключить события прокрутки
  2. Изменение динамической высоты списка

Здесь вы являетесь вспомогательным классом, который позволяет отключить прокрутку в виде списка:

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

Это код Joe Blow (комментарий к сообщению OP), указанный на http://danosipov.com/?p=604, но я размещаю его здесь, чтобы сохранить его, если ссылка потеряна:

 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); } } 

Когда вы добавляете этот ListView в свой макет, помните, чтобы предшествовать ему с его именем пакета, иначе исключение будет выброшено, когда вы попытаетесь его раздуть.

Попробуй это:

 listViewObject.setTranscriptMode(0); 

Работает на меня.