如何处理片段内的UI事件的简单方法(onClick等)

时间:2018-12-14 13:50:55

标签: android rx-android android-databinding

我正在尝试使用android的最新功能-Kotlin,mvvm,体系结构组件,jetpack,数据绑定,一项活动-许多片段采用了新的导航图,但是我正努力处理Fragments中的UI事件

在活动中,使用kotlin-android-extensions很简单 在XML中,我这样创建一个Button:

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

在“活动”中,我只是写

fun clicked(view : View){

}

那是完美的,但是不幸的是在Fragment中不起作用。是的,仍然可以在Activity中处理事件并将其发送到片段,但这很丑。

下一个选项是使用界面,

public interface MyClickCallback{
    void onLoginButtonClick();
}

在片段中实现它。 在xml中看起来像这样:

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

然后在片段的onCreateView中,我必须将clickCallback设置为片段,最后我可以使用它

@Override fun onLoginButtonClick() {

}

我遇到的问题是声明接口,并在每个新的UI事件上增强此接口并更新实现该接口的片段

下一个选项是RxView。单击所有功能看起来非常不错的东西。例如:

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();
        });

这里的问题是我必须将其绑定到UI组件-mSearchBtn。我不想这样 :-)。除非确实需要,否则我不想在片段中包含任何UI组件。我总是通过这样在布局中声明的变量与布局文件通信

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

我希望将其绑定到在Button中设置的XML中声明的变量

android:onClick="myclick"

但是我没有找到方法。

有人可以通过其他简单而不错的选择来帮助我吗?

2 个答案:

答案 0 :(得分:0)

在数据绑定布局中,创建一个View.OnClickListener类型的变量:

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

将其设置为您的“视图”:

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

在您的Fragment中,创建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()
        }
    });

答案 1 :(得分:0)

  

使用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 
    }
}

但是,如果您确实要为此使用数据绑定和布局,请在数据绑定布局文件中设置回调lambda。

<?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>