Включение метода `onClick` в пользовательском представлении FrameLayout - PullRequest
0 голосов
/ 24 января 2019

Я не могу заставить onClick метод работать с пользовательским представлением FrameLayout.

Когда я реорганизую Button представление по умолчанию в пользовательское представление ProgressButton, содержащее Button, метод onClick не вызывается.

Пользовательский ProgressButton Просмотр класса:

class ProgressButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = 0,
    defStyleRes: Int = 0
) : FrameLayout(context, attrs, defStyle, defStyleRes){

    private var button: Button

    init {
        val view = LayoutInflater.from(context).inflate(R.layout.view_progress_button, this, true)
        button = view.findViewById(R.id.button)
        context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.ProgressButton,
            0, 0
        ).apply {
            try {
                if (hasValue(R.styleable.ProgressButton_buttonText)) {
                    button.text = getString(R.styleable.ProgressButton_buttonText)
                }
                if (hasValue(R.styleable.ProgressButton_buttonBackground)) {
                    button.background = getDrawable(R.styleable.ProgressButton_buttonBackground)
                }
            } finally {
                recycle()
            }
        }
    }
}

ProgressButton Файл макета XML: res/layout/view_progress_button.xml

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

    <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            />

</FrameLayout>

Использование ProgressButton просмотра с android:onClick:

<com.example.ui.common.ProgressButton
        android:id="@+id/progress_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{() -> viewModel.onProgressButtonClick()}"
        app:buttonText="@string/test"
        app:buttonBackground="@drawable/selectable_button_blue"
/>

Как лучше всего передать прослушиватель кликов в пользовательское представление с помощью привязки данных Android?

1 Ответ

0 голосов
/ 24 января 2019

Предполагается, что в вашем build.gradle определено dataBinding.enabled true.Если нет, отметьте this out.

Не похоже, что ваш макет в настоящее время является макетом с привязкой к данным.Сначала вам нужно преобразовать view_progress_button.xml в макет привязки данных, как показано ниже:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <variable
            name="viewModel"
            type="com.your.package.YourViewModelClass" />
    </data>

    <FrameLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <com.example.ui.common.ProgressButton
        android:id="@+id/progress_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="@{() -> viewModel.onProgressButtonClick()}"
        app:buttonText="@string/test"
        app:buttonBackground="@drawable/selectable_button_blue"
        />

</FrameLayout>

В Android Studio должен быть параметр, позволяющий автоматически преобразовывать макет.Сделайте это, нажав alt + enter (Windows) или option + enter (OSX) в корневой ViewGroup в вашем макете.В этом случае вы захотите нажать эту комбинацию на свой FrameLayout.

В вашем классе ProgressButton вы захотите сделать что-то вроде этого:

val binding: ViewProgressButtonBinding = DataBindingUtil.inflate(getLayoutInflater(), R.layout.view_progress_button, null, false);

вместо:

val view = LayoutInflater.from(context).inflate(R.layout.view_progress_button, this, true)

Используя объект binding, вы можете сделать:

binding.setViewModel(yourViewModelInstance)

Вы можете создать экземпляр вашей ViewModel, но внутри вашего класса ViewModel вы должны определить onProgressButtonClick().

Если я правильно помню, вам может потребоваться сделать что-то подобное в вашем макете для onClick:

android:onClick="@{(v) -> viewModel.onProgressButtonClick()}"

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

Еще одно замечание: вам больше не нужно делать findViewById, поскольку у вас есть доступ к этому виду, например:

binding.button
...