Android 数据绑定onClick不工作

Android 数据绑定onClick不工作,android,data-binding,onclick,android-databinding,Android,Data Binding,Onclick,Android 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(ge

我开始使用数据绑定,我的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));
}
@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;
}
GameFragment.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));
}
@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\u 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_width="0dp"
            android:layout_height="0dp"
            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" />
(...)
<data>
    <variable
        name="myHandlers"
        type="co.package.MyHandlersListener" />
</data>

<com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/my_id"
                        android:layout_width="@dimen/full_width"
                        android:layout_height="wrap_content"
                        android:onClick="@{() -> myHandlers.doSomething()}" />

(...)
加载图像正在工作,但单击“不执行任何操作…”。。。
编译中没有错误,按钮点击设备时没有崩溃,控制台中没有结果…

请使用以下代码检查:

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

<com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/my_id"
                        android:layout_width="@dimen/full_width"
                        android:layout_height="wrap_content"
                        android:onClick="@{() -> viewModel.doSomething()}" />
/* My Handler Methods */

interface MyHandlersListener {
    fun doSomething()
}
您已编写为调用单击图像为:

 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>
  • 在使用视图绑定处理程序之前,使用java类或Activity类实现处理程序,如下所示:
  • mItemListener=新MustVisiteTimListener(){}

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

    mbinding.setHandler(mItemListener);
    

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

    <data>
        <variable
            name="viewModel"
            type="co.package.MyViewModel" />
    </data>
    
    <com.google.android.material.textfield.TextInputEditText
                            android:id="@+id/my_id"
                            android:layout_width="@dimen/full_width"
                            android:layout_height="wrap_content"
                            android:onClick="@{() -> viewModel.doSomething()}" />
    
    /* My Handler Methods */
    
    interface MyHandlersListener {
        fun doSomething()
    }
    
    然后实现侦听器,考虑到方法something是在活动/片段类中定义和实现的:

    private val myHandlersListener: MyHandlersListener = object : MyHandlersListener {
        override fun doSomething() {
            something()
        }
    }
    
    使用数据绑定,您可以将处理程序设置到布局类中(这可以在onCreate或onCreateView方法中完成,具体取决于您分别使用的是和activity还是fragment):

    通过这种方式,它可以完美地工作,您可以遵循Android团队提供的指南:

    请检查下面的答案,并告诉我天气是否有用,谢谢这可能会有帮助我添加了“v”到XML文件,它仍然不起作用。现在我试着像你写的那样做,但我从来没有做过这样的事情,所以这可能需要一些时间…当然,是的,在适配器/绑定方法中使用RecyclerView需要绑定来处理EventData绑定需要时间。在onclick lambda中,无论是否使用param v,它似乎都不能以这种方式工作。问题:在片段/活动中创建处理程序作为接口,而不是创建单独的处理程序类,这有什么原因吗?我认为名称令人困惑,我的意思是,我们不是使用Handlers对象,而是使用名称中包含handler的接口方法,您可以更改它。。使用此接口的想法是避免将整个活动/片段发送到布局,并可能注入一些泄漏