【问题标题】:Focusable Button in ListviewListview 中的可聚焦按钮
【发布时间】:2016-08-27 10:04:08
【问题描述】:

对于具有如下自定义行布局的 ListView:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="match_parent">


    <Button
    android:layout_width="51dp"
    android:layout_height="43dp"
    android:id="@+id/btnBin"
    android:focusable="false"
    android:focusableInTouchMode="false"
    android:background="@drawable/ktape" />

    <TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
     android:textAppearance="?android:attr/textAppearanceLarge"
     android:text="Temporary"
    android:id="@+id/txtShowUsername"
    android:layout_gravity="center_horizontal"
    android:layout_weight="1"
    android:paddingTop="20dp"
    android:gravity="right"
       android:paddingRight="10dp" />
</LinearLayout>

按钮不应该是可聚焦的,让 ListView 的 OnItemClickListener 执行:

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

为什么我需要将焦点设置为 false?为什么可聚焦按钮会阻止 OnItemClickListener.OnItemClick() 执行?

【问题讨论】:

  • 会发生什么?项目点击监听器是否正常工作?
  • @Raghunandan,我想知道为什么我需要将焦点设置为 false。
  • 你可以看源码,找出原因

标签: android listview focusable


【解决方案1】:

当您触摸屏幕上的某些东西时,触摸手势是通过布局的根视图获得的。然后它将触摸手势一一传递给它的孩子,直到它被消耗掉。如果孩子是可点击的视图,那么它会使用触摸手势并返回 true。这样触摸手势就不会传递给其他View。如果孩子不是可点击的View,那么它只是返回false,触摸手势将传递给下一个孩子。

最后,如果没有子视图消耗触摸手势,它将被发送回父视图本身。现在父母可以使用触摸手势,如果有的话。

现在,在您的情况下,ListView 是父级,而 Button 是子级。首先,ListView 将触摸手势传递给按钮。由于button默认是一个可点击的View,它会消耗触摸手势,所以ListView的OnItemClickListener不起作用。通过显式设置focusable、focusableInTouchMode、clickable为false,按钮变为不可点击View。所以按钮不会消耗触摸手势,ListView的OnItemClickListener可以工作。

【讨论】:

  • 感谢您的回答。您知道,通过将 focusable 设置为 false,我可以为按钮设置 clickListener,为列表项设置 itemClickListener,并且效果很好。总之,按钮还是可以点击的。
  • 理想情况下,当您点击按钮时,按钮的 ClickListener 将起作用,而 ListView 的 OnItemClickListener 不会触发。当你点击ListView项(不是Button)时,ListView的OnItemClickListener会起作用,而Button的ClickListener不会被触发。
  • 我认为,您应该将属性 android:descendantFocusability="blocksDescendants" 添加到 ListView 项的根布局中,而不是 android:focusable="false"。 developer.android.com/reference/android/view/…
【解决方案2】:

尝试添加这一行:

android:clickable="false"

【讨论】:

  • 这段代码有效,我想知道为什么我需要将focusable设置为false。
  • 我不确定,但我认为如果您在可聚焦为真且可点击为假时单击按钮时不这样做,则不会发生任何事情(甚至来自 listview 的 onitemclick)
  • 是的,这是真的。但我想知道为什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多