Как создать собственное представление с настраиваемым атрибутом, который поддерживает привязку данных? - PullRequest
0 голосов
/ 21 июня 2019

Я создал пользовательскую кнопку для отображения подтверждения AlertDialog до фактического вызова слушателя onClick, см. Ниже.

public String getMessageText() {
    return messageText.get();
}

public void setMessageText(String text) {
    messageText.set(text);
}

/**
 * Opens an {@link AlertDialog} with the constructed attributes and calls
 * {@code super.performClick()} if the positive button is pressed and
 * does nothing if the negative button is pressed.
 *
 * @return {@code true}
 */
@Override
public boolean performClick() {

    final AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
            .setTitle(titleText.get())
            .setMessage(messageText.get())
            .setPositiveButton(confirmText.get(), (dialog, which) -> super.performClick())
            .setNegativeButton(cancelText.get(), null)
            .show();

    return true;
}

Я не включил конструкторы и функцию init для краткости.Представление поддерживает следующие атрибуты (values ​​/ attrs.xml):

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="ConfirmationButton">
        <attr name="titleText" format="reference|string" />
        <attr name="messageText" format="reference|string" />
        <attr name="confirmText" format="reference|string" />
        <attr name="cancelText" format="reference|string" />
    </declare-styleable>
</resources>

И я могу использовать это следующим образом.

Использование привязки данных:

<com.example.app.ConfirmationButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"        
        app:messageText="@{vm.message_text}"
        android:text="Click this button" />

Или используя идентификатор ссылки на строку:

<com.example.app.ConfirmationButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"         
        app:messageText="@string/app_name"
        android:text="Click this button" />

Если я Изменить имя setMessageText () на setMsgText ().Затем сработает следующее:

<com.example.app.ConfirmationButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"        
        app:msgText="@{vm.message_text}"
        android:text="Click this button" />

Поскольку используется привязка данных, и он находит метод ConfirmationButton # setMsgText (String).

Теперь это не работает.

<com.example.app.ConfirmationButton
        android:layout_width="match_parent"
        android:layout_height="wrap_content"        
        app:msgText="@string/app_name"
        android:text="Click this button" />

Что для меня вроде имеет смысл, но это приводит меня к вопросу.Почему это работает в первую очередь, когда имя атрибута styleable и сеттера совпадают?Потому что это не похоже на стабильный способ разрешить привязку / строку / привязку данных к атрибуту.Это действительно единственный способ заставить все это работать?Это как Android делает это на примере TextView с android: text?

Моей первой идеей было сделать следующий BindingAdapter, он игнорируется из-за столкновения приложения пространства имен: messageText:

@BindingAdapter(value = "app:messageText")
public static void setMessageText(ConfirmationButton btn, String text) {
    btn.setMessageText(text);
}

Затем я, наконец, выбрал решение, приведенное выше (чтобы сопоставить метод setter с атрибутом styleable).

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

...