禁用listview中的滚动

时间:2011-09-30 13:28:46

标签: android listview scroll listener

我有一个列表视图,根据某些逻辑,我想暂时禁用滚动。 view.setOnScrollListener(NULL);不能帮助我我想我需要编写一些代码,有人可以给我一个文件或一些片段吗?

由于

10 个答案:

答案 0 :(得分:43)

如果动作事件操作为onTouchListener,则不创建新自定义ListView的另一个选项是将onTouch()附加到ListView并在ACTION_MOVE回调中返回true。

listView.setOnTouchListener(new OnTouchListener() {

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

答案 1 :(得分:41)

在CustomListView中:

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

然后ListView会对点击作出反应,但不会改变滚动位置。

答案 2 :(得分:27)

使用 listview.setEnabled(false)禁用列表视图滚动

注意:这也会禁用行选择

答案 3 :(得分:8)

如果您有一个绑定到列表项的事件,则使用这些解决方案中的任何一个拖动列表仍将触发该事件。您希望使用以下方法来考虑用户期望通过拖离所选项目来取消事件(改编自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

答案 4 :(得分:7)

制作CustomListView

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

false上,孩子们会处理触摸事件,请确保将if condition检查是否需要滚动。

答案 5 :(得分:5)

对我来说最好的答案是丹·奥西波夫的一个人。 我会像这样改进它。 (触发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);
}

答案 6 :(得分:2)

在列表视图中编写用于滑动删除的代码时,我想在检测到滑动后阻止垂直滚动。一旦满足滑动删除条件,我在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);
}

答案 7 :(得分:1)

对于Xamarin和MvvmCross用户,我的回答会很有趣。主要概念与之前的帖子相同,因此主要步骤是:

  1. 静音滚动事件
  2. 动态更改列表高度
  3. 这里你是帮助类,允许在列表视图中禁用滚动:

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

答案 8 :(得分:1)

这是代码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添加到布局时,请记住在其前面加上其包名称,否则在尝试对其进行充气时会抛出异常。

答案 9 :(得分:1)

试试这个:

listViewObject.setTranscriptMode(0);

适合我。