Я создал пользовательскую кнопку для отображения подтверждения 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).
Я хотел бы получить объяснение передового опыта, как наилучшим образом разрешить привязку строк, идентификаторов и данныхв пользовательском представлении.