数据绑定 onClick 不起作用

Posted

技术标签:

【中文标题】数据绑定 onClick 不起作用【英文标题】:Data Binding onClick not working 【发布时间】:2018-12-27 08:16:35 【问题描述】:

我开始使用 DataBinding,但我的 onClick 出了点问题。

GameViewModel.java

public void onClickItem(int row, int col)
    Log.d("click","row: "+row+" col: "+col);

@BindingAdapter("load_image")
public static void loadImage(ImageView view,int imageId) 
    view.setImageResource(getDrawable(imageId));

GameFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) 
    //View view=inflater.inflate(R.layout.fragment_game, container, false);
    FragmentGameBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_game, container, false);
    View view = binding.getRoot();
    ButterKnife.bind(this,view);
    binding.setGameViewModel(gameViewModel);
    gameViewModel= ViewModelProviders.of(getActivity()).get(GameViewModel.class);
    gameViewModel.init();
return view;

fragment_game.xml

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"

tools:context=".view.GameFragment">

<data>
     <import type="android.support.v4.app.Fragment"/>
    <import type="android.view.View"/>

    <variable
        name="gameViewModel"
        type="harkor.addus.viewmodel.GameViewModel" />
</data>


<android.support.constraint.ConstraintLayout
   (...)>

    <TextView
        (...)>

    <android.support.constraint.ConstraintLayout
        (...)>

        <ImageView
            android:id="@+id/image_puzzle11"
            android:src="@android:color/holo_green_dark"
            android:layout_
            android:layout_
            android:layout_marginEnd="1dp"
            android:layout_marginRight="1dp"
            android:onClick="@() -> gameViewModel.onClickItem(1,1)"
            app:load_image="@0"
            app:layout_constraintBottom_toTopOf="@+id/image_puzzle21"
            app:layout_constraintDimensionRatio="w,1:1"
            app:layout_constraintEnd_toStartOf="@+id/image_puzzle12"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
(...)

load_image 正在工作,但 onClick 什么也不做... 编译没有错误,点击设备时没有崩溃,控制台没有结果......

【问题讨论】:

请检查下面的答案,让我知道天气有用与否,谢谢 developer.android.com/topic/libraries/data-binding/… 这可能会有所帮助 【参考方案1】:

请检查以下代码:

你已经写了作为点击图像调用:

 android:onClick="@() -> gameViewModel.onClickItem(1,1)"

尝试如下写并再次检查:

android:onClick="@(v) -> gameViewModel.onClickItem(1,1)"

根据指南,这不是实现架构原则的方法,我们可以按照 MVVM 架构如下工作: 1.创建接口 2. 将接口定义为布局文件中的处理程序:

<variable
        name="handler"
        type="com.cityguide.interfaces.MustVisitItemListener"></variable>

3.现在我们正在使用这个处理程序将 onclick 定义为:

android:onClick="@(v) ->handler.onGalleryItemClick(v,currentPosition,photo)"
    在将 Handler 与 View 绑定之前,先用我们的 java 类或 Activity 类实现 Handler,如下所示:
private MustVisitItemListener mItemListener;

mItemListener = new MustVisitItemListener() ;

5.使用绑定对象设置接口处理程序如下:

mbinding.setHandler(mItemListener);

【讨论】:

我在 XML 文件中添加了“v”,但它仍然无法正常工作。现在我试着像你写的那样做,但我从来没有做过这样的事情,所以可能需要一些时间...... 当然,举办活动需要时间 与 RecyclerView 的数据绑定需要在 Adapter/Bind 方法中进行绑定。无论是否在 onclick lambda 中使用参数 v,它似乎都无法以这种方式工作。【参考方案2】:

最简单的方法是设置视图模型并从布局中调用视图的 onClick 中的正确方法: 您的 xml:

<data>
    <variable
        name="viewModel"
        type="co.package.MyViewModel" />
</data>

<com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/my_id"
                        android:layout_
                        android:layout_
                        android:onClick="@() -> viewModel.doSomething()" />

但是如果出于任何原因需要从片段或活动中调用方法,最好的建议是创建一个接口来处理该方法,实现该方法并将其设置为如下布局: 你的 xml

<data>
    <variable
        name="myHandlers"
        type="co.package.MyHandlersListener" />
</data>

<com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/my_id"
                        android:layout_
                        android:layout_
                        android:onClick="@() -> myHandlers.doSomething()" />

然后在 Fragment 或 Activity 中创建接口,然后实现它: 您的活动/片段:

/* My Handler Methods */

interface MyHandlersListener 
    fun doSomething()

然后实现监听器,考虑到方法 something 在您的活动/片段类中定义和实现:

private val myHandlersListener: MyHandlersListener = object : MyHandlersListener 
    override fun doSomething() 
        something()
    

并且使用数据绑定,您可以将处理程序设置到您的布局类中(这可以在 onCreateonCreateView 方法中完成,具体取决于您使用的是活动还是片段分别):

myBinding.myHandlers = myHandlersListener

通过这种方式,它可以完美运行,并且您可以按照 Android 团队提供的指南进行操作: https://developer.android.com/topic/libraries/data-binding/expressions#method_references

【讨论】:

问题:是否有理由将处理程序创建为片段/活动中的接口而不是创建单独的处理程序类? 我觉得这个名字很混乱,我的意思是,我们不是用 Handlers 对象做的,而是用名字里有 handler 的接口方法,你可以改变它.. 使用这个接口的想法是避免将整个活动/片段发送到布局并可能注入一些泄漏

以上是关于数据绑定 onClick 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Android数据绑定onLongClick不起作用

jsp 中onclick不起作用

小部件 Onclick 不起作用

onclick()在表中不起作用

为啥我的“onclick()”事件在 Angular 中不起作用?

OnClick 在 iOS11 上不起作用