ListView的OnItemClickListener没有响应?

45
我已经到处寻找解决方案,但我无法弄清楚如何实现它。我的 ListView 行的 OnItemClickListener 被禁用了,因为在行布局中有一个 ImageButton,它接管了焦点。我发现了许多类似的问题,但没有一个能帮我解决。

我查看了这个问题,但我无法理解其中的内容。我只需要一种方法,使得行可以被点击,以便我可以检测到何时按下行,长按和聚焦都可以正常工作。

12个回答

60

在您的适配器中为每个视图添加一个OnClickListener,而不是使用OnItemClickListener。您需要使用setItemsCanFocus来设置列表:

ListView list = (ListView) findViewById(R.id.myList);
list.setAdapter(new DoubleClickAdapter(this));
list.setItemsCanFocus(true);

然后在您的适配器getView中,这将产生一个可点击的行。假设该按钮位于充气的xml中。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = View.inflate(context, R.layout.cell, null);
    view.setClickable(true);
    view.setFocusable(true);
    view.setBackgroundResource(android.R.drawable.menuitem_background);
    view.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            new AlertDialog.Builder(context).setTitle("touched").show();
        }

    });
    return view;
}

47
别忘了回收视图!使用convertView,不要每次都重新膨胀一个新的视图。 - Romain Guy
我基本上已经做到了,尽管我感觉在做某些事情时遇到了问题。我会再试一次,也许只是一个愚蠢的错误。 - Kleptine
1
如果您仍希望整行可点击,则此解决方案并不理想,您应该使用https://dev59.com/sXE95IYBdhLWcg3wUMHW#4518810。 - Heath Borders
如果我在扩展的CursorAdaptornewView()中执行它,而不是在getView()中执行它,那么它就无法正常工作。出了什么问题? - faizal
我现在已经卡在这个问题上6个小时了,真的需要帮助。http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 - Ruchir Baronia
显示剩余2条评论

53

设置你的 ImageButton 的属性:

android:focusable="false"

因为 AbsListView.onTouchEvent 检查 child.hasFocusable()


4
对于TextView来说很好用,对于按钮则不太适用。 - Ian
如果您在TextView中使用了android:inputType属性,那么您也应该将其删除。 - Nguyen Minh Binh
比获奖答案更好的选择。注册单个监听器,并处理它。启动时使用更少的内存。 - chubbsondubs
我现在卡在这里已经6个小时了,真的需要帮助。http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 - Ruchir Baronia
添加另一个发现 - 不要使用“View”小部件,而应使用ImageView或适用的小部件。 - Swas_99

10
我在SDK 8和16上测试了以下解决方案。
在`getView()`方法中,
setFocusable(false);
setClickable(false);

在适配器的 getView() 中不设置为 true 而是在那里执行想要的操作,这样就可以调用 OnItemClickListener(前提是在 getView() 中没有设置 OnClickListener)。我认为这才是原始问题所想要的。

我假设你可以在 View 的 OnClickListener 中做的任何事情都可以在 ListViewOnItemClickListener 中同样轻松地完成。(在 View 上设置 setOnClickListener 隐式地将该视图设置为可点击状态,这会防止 ListView 对应的 OnItemClickListener 被调用。)

在按下或滑过项时,ImageButton的可视状态与预期一致。

这个解决方案有一个小小的幻觉,即被按下的是列表项而不是 ImageButton 本身,因此,如果按钮不占据整个列表项,则在项目的其他位置单击仍会使按钮的可绘制状态反映出单击。聚焦也是一样的。这可能是值得付出的代价。


4
如果你的ListView行有多个可点击项,你可以在顶层列表项布局上设置 android:descendantFocusability="blocksDescendants",并且不在从getView()方法返回的视图上设置 OnClickListener,这样可以实现你想要的效果。在单独的项目上设置 OnClickListener 仍然有效。 - JulianSymes
1
这个解决方案对我也起作用了。在我的情况下,当单选按钮被点击时,我没有在OnItemClickListener中收到点击事件。 - HemangNirmal
我已经卡在这里6个小时了,我真的需要帮助。http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 - Ruchir Baronia

7
这一定会奏效。将此添加到布局定义中。
android:descendantFocusability="blocksDescendants" 

这里找到了解决方案。


5

最好的方法是这样的:

  android:focusable="false"
  android:focusableInTouchMode="false"

设置这些属性来尝试使用Imagebutton


5

为了避免为每个视图设置OnClickListener,可以选择不使用ImageButton,而改用ImageViewImageView仍然可以将事件发送给OnClickListener,并且不会占据焦点。


4

针对我的这个问题,问题出在我将 TextView 对象设置为 android:inputType="textMultiLine"。 当我删除了这行代码后,列表无法点击的问题消失了。 看起来是一个很讨厌的小bug。

此外,我仍然可以毫无问题地使用 android:minLines/android:maxLines 属性,所以这并不是一个大问题。 只是不是我期望的解决方案。


我已经卡在这里6个小时了,我真的需要帮助。http://stackoverflow.com/questions/35108940/why-cant-i-remove-an-item/35109304#35109304 - Ruchir Baronia

1
以下这行代码解决了我的项目中的问题:
<TextView ... android:textIsSelectable="false" />

1
作为一个替代方案,对我有效的方法是尝试从BaseAdapter扩展你的适配器(而不是实现ListAdapter接口)。

0

我已经对ImageButton进行了子类化,并且在布局定义中使用setFocusable ="false"无法解决我的问题。这个问题可以通过在子类的构造函数中调用setFocusable(false)来解决。


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