何时应该使用android:clickable?

23

我们什么时候应该在XML中使用android:clickable?我们有必要使用吗?
这种XML声明和在代码中使用myButton.setOnClickListener有什么区别?我已经阅读了文档,但是我仍然无法确定何时以及为什么应该使用此属性。

PS. 我正在实现一个广告SDK,发现他们的开发人员在WebView中使用了android:clickable,我很好奇他们为什么要这样做。

6个回答

10

clickable在需要使点击事件不传递到最上层视图下方的视图时非常有用。

例如,我有一个FrameLayout,它会在某些时候显示在一个底部的RelativeLayout之上。当用户点击一个底部的EditText时,焦点会转移到该EditText,这样会非常烦人,因为此时FrameLayout仍然显示在顶部。现在用户不知道为什么键盘弹出了或他们正在输入的位置。

当我在FrameLayout中设置clickable="true"时,用户就不能再意外地点击底部的EditText字段了。

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    ...>
    <EditText>
    <EditText>
    <EditText>
    <!-- FrameLayout with grayed-out background. -->
    <FrameLayout
        android:id="@+id/sometimes_visible_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#80808080"
        android:clickable="true"
        android:visibility="gone"
        android:focusable="true"
        ...>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            ...>
            <View>
            <View>
        </LinearLayout>
    </FrameLayout>
</RelativeLayout>

8
根据文档和我的了解:

clickable - 定义此视图是否对点击事件做出反应。 必须是一个布尔值,"true" 或 "false"。

例如,如果您只在 layout.xml 中声明了一个 WebviewView 并尝试为这些视图设置 OnClickListener,除非指定属性:clickable="true",否则 OnClick 事件将不会被触发。
  android:clickable=true

3
我有疑惑。如果我有一个按钮或其他视图,我从来没有使用过这个值,但我可以实现 onClickListener。我觉得我没有理解你所说的。 - sandalone
18
setOnClickListener使View可以被点击。文档 - FunkTheMonk
1
@FunkTheMonk 谢谢。现在回到我的问题:如果我可以实现onClickListener,我为什么要使用android:clickable?它的使用场景是什么? - sandalone
2
@bergnam,对于实现OnClickListener的活动,您可以将onClick="onClick"放置在onClickListener(this)之前,从而具有相同的方法原型[public void onClick(View v)],而不需要您的活动实现OnClickListener。为什么?为了好玩。当您不想使视图启用=false,但又不想取消/重新分配onClick监听器时,可以设置clickable=false。您可能希望在单击时视图具有不同的绘制状态,但不执行任何操作。设置clickable=true和setOnClickListener是多余的。两者都有用途。 - FunkTheMonk
1
我认为你应该把这放在一个答案中。 - Ovidiu Latcu
显示剩余2条评论

2
当您在任何视图上设置 view.setOnClickListener,比如说 myButton.setOnClickListener(new OnClickListener),默认情况下会将其视为 clickable="true"。因此,您不需要在 XML 文件中提及像 android:clickable="true" 这样的内容。使用 onClick() 事件时,无需使用 android:clickable="true" 就可以触发该事件。

1
当您使用android:onClick=""属性或以编程方式调用setOnClickListener(...)时,View类会将clickable标志设置为true。请注意。
/**
 * Register a callback to be invoked when this view is clicked. If this view is not
 * clickable, it becomes clickable.
 *
 * @param l The callback that will run
 *
 * @see #setClickable(boolean)
 */
public void setOnClickListener(@Nullable OnClickListener l) {
    if (!isClickable()) {
        setClickable(true);
    }
    getListenerInfo().mOnClickListener = l;
}

关于何时应该自行设置可点击标志,我认为主要是当你希望一个视图可点击时,例如停止在加载某些数据时的重复调用等情况。

1
我曾经遇到过这样的情况,我将一个活动设置为可滑动(向左/向右或向右/向左移动以前进/后退)。在某些屏幕上,有些地方只填充了一个LinearLayout。该布局没有OnClickListener(不需要),导致在LinearLayout上执行滑动操作时无法注册。设置android:clickable="true"解决了这个问题。
回答您的问题,并如上所示,有些情况下使用clickable属性是有用的。
我不认为您可以说设置OnClickListener与设置clickable属性相同,但是设置OnClickListener确实使View可点击,在那种特定情况下使clickable属性无用。

如果您将LinearLayout设置为可点击,并且它具有子元素,Android如何区分我是要触发元素的onClick还是布局的onClick?它是否像这样工作:如果我触摸元素,则会触发其onClick,如果我单击空白区域(在布局内部),则会触发LinearLayout的onClick - sandalone
是的,那就是会发生的事情。尽管在我上面的例子中没有为LinearLayout注册onClick事件 - 我只需要它来注册点击事件以便将它们传递给我的滑动功能。 - kaspermoerch

0

我不知道为什么在那种情况下要使用它,但是当我创建一个继承自LinearLayout的类时,我不得不使用它。

我创建了自己的“控件”,并且希望它可以被点击,所以我必须使用它。

这是你需要使用它的一种情况。


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