Когда нужно использовать android: clickable?

Когда мы должны использовать android:clickable в XML? Должны ли мы когда-либо?
Есть ли разница между таким объявлением XML и объявлением в коде myButton.setOnClickListener? Я прочитал документацию, но я не мог узнать, когда и почему я должен использовать этот атрибут.

PS. Я реализовал рекламный SDK и обнаружил, что их разработчики использовали android:clickable с WebView, и я был заинтригован, почему они его использовали.

Ответ 1

Как указано в документации, и насколько я знаю:

clickable - определяет, реагирует ли это представление на события кликов. Должно быть логическое значение, либо "true", либо "false".

Так, например, если вы просто объявляете Webview или View в своем layout.xml и пытаетесь установить OnClickListener в этих представлениях, событие OnClick не будет запущено, если вы не укажете атрибут:

  android:clickable=true

Ответ 2

clickable кажется полезным, когда вам нужно, чтобы просмотр потреблял клики, чтобы они не переходили к представлениям под верхним видом.

Например, у меня есть FrameLayout, который я показываю над базовым RelativeLayout в определенное время. Когда пользователь нажмет на основной EditText, фокус переместится на EditText. Действительно раздражает, когда FrameLayout все еще отображается. Теперь пользователь не знает, почему клавиатура просто выскочила или где они печатают.

Когда я установил clickable="true" в FrameLayout, пользователи больше не могли случайно называть базовые поля 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>

Ответ 3

Когда вы устанавливаете view.setOnClickListener на любом View, например: myButton.setOnClickListener(new OnClickListener) по умолчанию считается как clickable="true".

Поэтому вам не нужно упоминать об этом в XML файле, например android:clickable="true". Событие onClick() будет запущено без использования android:clickable="true".

Ответ 4

У меня возникла ситуация, когда я сделал операцию swipeable (проведите влево/вправо или вправо/влево, чтобы двигаться вперед/назад). На некоторых экранах были места, которые были заполнены только LinearLayout. Для макета не было OnClickListener (это не было необходимо), в результате чего действие салфетки не регистрировалось при выполнении LinearLayout. Установка android:clickable="true" решила проблему.

Чтобы ответить на ваши вопросы и как показано выше, бывают ситуации, когда использование атрибута clickable может быть полезным.

Я не верю, что вы можете сказать, что установка OnClickListener такая же, как установка атрибута clickable, но установка OnClickListener, безусловно, делает View доступным для клика, создавая атрибут clickable -attribute бесполезно (в этой конкретной ситуации).

Ответ 5

Я не знаю, почему они использовали в этом случае, но мне пришлось использовать его, когда я создал класс, который расширял linearLayout.

Я создал свой собственный "контроль", и я хотел, чтобы он был кликабельным, поэтому мне пришлось его использовать.

Это один из сценариев, когда вы будете использовать его

Ответ 6

FYI; Когда вы используете программный атрибут 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;
}

Что касается того, когда вы должны установить самозахватываемый флаг самостоятельно, я думаю, в основном, когда вы хотите, чтобы представление не было взломанным, например, чтобы остановить повторные вызовы во время загрузки некоторых данных и т.д.