当触摸自定义视图时,不要滚动 ListView

4
我创建了一个自定义视图,您可以在其中使用手指绘制路径。它扩展了View类。
当我将其用作ListView的一个项目时,如果用户触摸自定义视图,则ListView会滚动。我该如何防止发生这种情况?
我想我需要以某种方式聚焦于我的自定义视图。但是我不知道如何做到这一点。
更新:
我找到了可能的解决方案。在我的自定义视图的onTouchEvent(Motion event)方法中,我放置了getParent()。requestDisallowInterceptTouchEvent(true)。
没有这个选项时,当用户触摸自定义视图时,事件队列看起来像这样:
MotionEvent.ACTION_DOWN MotionEvent.ACTION_MOVE MotionEvent.ACTION_MOVE MotionEvent.ACTION_CANCEL
当我收到具有代码MotionEvent.ACTION_CANCEL的MotionEvent时,ListView开始滚动。

你能从所使用的适配器中获得视图的索引吗?因为如果可以,那么只需要使用 setSelection() 就行了。 - Swayam
@Swayam 视图除了自定义视图之外还包含其他几个视图。setSelection()选择一行,这不是我需要的。 - Slava
请原谅我的天真,但如果您选择包含自定义视图的行,那么这不就是您要的吗? - Swayam
@Swayam 我不需要选择行。我需要在触摸自定义视图时防止listview滚动。如果选择一行,listview仍然可以滚动,是吗? - Slava
哦,好的好的.. 直到现在我才真正理解你的问题。我会看一下并尝试让它工作。在那之前,祝你一切顺利。 - Swayam
2个回答

3

在子视图的 onTouch(View, MotionEvent) 方法中设置 requestDisallowInterceptTouchEvent(true) 可以生效:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        ViewGroup item = (ViewGroup) inflater.inflate(R.layout.list_item, null);
        Button button = (Button)item.findViewById(R.id.list_item_btn);
        button.setText("button " + position);

        button.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                listView.requestDisallowInterceptTouchEvent(true);
                return false;
            }

        });

        return item;
    }

谢谢。对于我来说,调用v.getParent().requestDisallowInterceptTouchEvent(true);就可以了,这样就可以使其独立于实际的ListView实例。 - mortalis

0

我认为你也应该扩展ListView小部件。

正如你所说,当你触摸自定义视图时,ListView将滚动。
当你触摸自定义视图时,触摸事件将沿着视图层次结构分发,
我认为ListView可能会吃掉触摸事件。
因此,你的自定义视图无法接收触摸事件。
如果你还没有理解触摸事件的分发。
你可以阅读这篇文章Managing Touch Events in a ViewGroup

最后。
我建议你扩展ListView并覆盖onInterceptTouchEvent()方法。
你可以决定ListView是否想在onInterceptTouchEvent()中处理触摸事件。
当你判断触摸事件应该由drawPathView处理时,
你可以让ListView不拦截它。
这样你的drawPathView就可以获取触摸事件。
而且listView也不会滚动


我认为这种方法对我不起作用。首先,我能够在自定义视图上画出非常短的线条,因此它只能接收到触摸事件一小段时间,然后就失去了焦点。其次,例如按钮,会防止ListView滚动:如果您点击ListView上的按钮并尝试滚动,这是不可能的。所以某种程度上它在那里可以正常工作。 - Slava
好的,我明白了。我认为ListView在垂直方向上移动的距离超过一定值后才会开始滚动,因此您可以绘制排序路径。当您绘制排序路径时,移动的距离小于触发距离。如果您移动的距离超过触发距离,ListView将开始滚动。您这样认为对吗? - yftx
我看到了你的更新消息。我建议你非常阅读我提到的那篇文章,然后你就会知道为什么会收到ACTION_CANCEL事件。 - yftx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接