Простой способ обработки событий пользовательского интерфейса внутри фрагмента (onClick, ...) - PullRequest
0 голосов
/ 14 декабря 2018

Я пытаюсь использовать последние функции Android - Kotlin, mvvm, компоненты архитектуры, jetpack, привязку данных, одно действие - многие фрагменты подходят с новым графом навигации, но я борюсь с обработкой событий пользовательского интерфейса во фрагментах

В действии все просто с kotlin-android-extensions В XML я создаю кнопку вроде этого:

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:onClick="clicked"/>

, а в действии я просто пишу

fun clicked(view : View){

}

Это прекрасно, но, к сожалению, не работает во фрагменте.Да, есть возможность обрабатывать событие в Activity и отправлять его во фрагмент, но это ужасно.

Следующий вариант - использовать интерфейс,

public interface MyClickCallback{
    void onLoginButtonClick();
}

реализовать это во фрагменте.В XML это выглядит так:

    <variable
        name="clickCallback"
        type="com.test.MyClickCallback" />

, затем в onCreateView фрагмента я должен установить clickCallback для фрагмента, и, наконец, я могу использовать его

@Override fun onLoginButtonClick() {

}

Проблема, с которой я сталкиваюсь, заключается в том, чтобыобъявляйте интерфейс и при каждом новом событии пользовательского интерфейса улучшайте этот интерфейс и обновляйте фрагмент, который его реализует

Следующая опция - RxView.clicks, которая действительно великолепно выглядит со всеми ее функциями. Например:

RxView.clicks(mSearchBtn)
        .throttleFirst(2, TimeUnit.SECONDS)
        .map(aVoid -> mSearchEdit.getText().toString().trim())
        .filter(s -> !TextUtils.isEmpty(s))
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(s -> {

          KeyBoardUtil.closeKeybord(mSearchEdit,
              SearchActivity.this);
          showSearchAnim();
          clearData();
          content = s;
          getSearchData();
        });

Проблема здесь в том, что я должен связать его с компонентом пользовательского интерфейса - mSearchBtn.Я не хочу это :-).Я не хочу иметь какой-либо компонент пользовательского интерфейса во фрагменте, если я действительно не должен.Я всегда общаюсь с файлом макета через переменные, объявленные в макете, как это

<data>
    <variable
        name="items"
        type="java.util.List" />
</data>

Я бы хотел связать его с переменной, объявленной в XML, которая установлена ​​в кнопке

android:onClick="myclick"

НоЯ не нашел способ, как это сделать.

Кто-нибудь может мне помочь, может быть, с другими простыми и приятными вариантами?

Ответы [ 2 ]

0 голосов
/ 16 декабря 2018

это просто с kotlin-android-extensions

Это действительно просто, но вы в настоящее время не используете его в полной мере.

Настройка прослушивателей кликовв Kotlin очень просто, посмотрите:

fun View.onClick(clickListener: (View) -> Unit) {
    setOnClickListener(clickListener)
}

А теперь благодаря синтетическому импорту в Kotlin-Android-Extensions:

<Button
    android:id="@+id/myButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="16dp"
    android:text="@string/click_me"/>

и

import kotlinx.synthetic.blah.* // something like that

// Activity:
override fun onCreate(bundle: Bundle?) {
    super.onCreate(bundle)
    setContentView(R.layout.blah)

    myButton.onClick {
        // handle click event 
    }
}

// Fragment:
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, bundle: Bundle?) = inflater.inflate(R.layout.blah, container, false)

override fun onViewCreated(view: View) {
    super.onViewCreated(view)

    myButton.onClick {
        // handle click event 
    }
}

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

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="activity" type="com.acme.MainActivity"/>
    </data>
    <RelativeLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/btnOpenSecondView"
            android:text="Click me for second view!"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:onClick="@{(v) -> activity.startNextActivity(v)}" />
    </RelativeLayout>
</layout>
0 голосов
/ 16 декабря 2018

В вашем макете привязки данных создайте переменную, имеющую тип View.OnClickListener:

<variable
    name="onClickListener"
    type="android.view.View.OnClickListener" />

Установите его на свой вид следующим образом:

<View
    ...
    android:onClickListener="@{onClickListener}"
    ... />

В своем фрагменте создайте onClickListenerи установите его в переменную:

binding.onClickListener = View.OnClickListener { 
    /* do things */
    /* like getting the id of the clicked view: */
    val idOfTheClickedView = it.id
    /* or get variables from your databinding layout: */
    val bankAccount = binding.bankAccount
}

Или в Java:

binding.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            /* do things */
            /* like getting the id of the clicked view: */
            Int idOfTheClickedView = view.getId();
            /* or get variables from your databinding layout: */
            Object bankAccount = binding.getBankAccount()
        }
    });
...