数据绑定 onClick 不起作用
Data Binding onClick not working
我正在开始使用 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_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" />
(...)
load_image 正在工作,但 onClick 什么都不做......
编译无错误,点击设备按钮无崩溃,控制台无结果...
请用下面的代码检查:
你写的调用图片点击为:
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.Now 我们正在使用此处理程序将 onclick 定义为:
android:onClick="@{(v) ->handler.onGalleryItemClick(v,currentPosition,photo)}"
- 使用我们的 java Class 或 Activity class 实现处理程序,然后将处理程序与视图绑定,如下所示:
private MustVisitItemListener mItemListener;
mItemListener = new MustVisitItemListener() { };
5.Set 具有如下绑定对象的接口处理程序:
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()}" />
但是如果出于任何原因你需要从片段或 activity 中调用方法,最好的建议是创建一个接口来处理该方法,实现该方法并将其设置为布局,如下所示:
你的xml
<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()}" />
然后在您的 Fragment 或 Activity 中创建接口然后实现它:
你的activity/fragment:
/* My Handler Methods */
interface MyHandlersListener {
fun doSomething()
}
然后实现侦听器,考虑到方法 something 是在您的 activity/fragment class:
private val myHandlersListener: MyHandlersListener = object : MyHandlersListener {
override fun doSomething() {
something()
}
}
并且使用数据绑定,您可以将处理程序设置到您的布局中 class(这可以在 onCreate 或 onCreateView 方法,具体取决于您分别使用和 activity 还是片段):
myBinding.myHandlers = myHandlersListener
通过这种方式,它可以完美运行,您可以按照 Android 团队提供的指南进行操作:
https://developer.android.com/topic/libraries/data-binding/expressions#method_references
我正在开始使用 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_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" />
(...)
load_image 正在工作,但 onClick 什么都不做...... 编译无错误,点击设备按钮无崩溃,控制台无结果...
请用下面的代码检查:
你写的调用图片点击为:
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.Now 我们正在使用此处理程序将 onclick 定义为:
android:onClick="@{(v) ->handler.onGalleryItemClick(v,currentPosition,photo)}"
- 使用我们的 java Class 或 Activity class 实现处理程序,然后将处理程序与视图绑定,如下所示:
private MustVisitItemListener mItemListener;
mItemListener = new MustVisitItemListener() { };
5.Set 具有如下绑定对象的接口处理程序:
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()}" />
但是如果出于任何原因你需要从片段或 activity 中调用方法,最好的建议是创建一个接口来处理该方法,实现该方法并将其设置为布局,如下所示: 你的xml
<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()}" />
然后在您的 Fragment 或 Activity 中创建接口然后实现它: 你的activity/fragment:
/* My Handler Methods */
interface MyHandlersListener {
fun doSomething()
}
然后实现侦听器,考虑到方法 something 是在您的 activity/fragment class:
private val myHandlersListener: MyHandlersListener = object : MyHandlersListener {
override fun doSomething() {
something()
}
}
并且使用数据绑定,您可以将处理程序设置到您的布局中 class(这可以在 onCreate 或 onCreateView 方法,具体取决于您分别使用和 activity 还是片段):
myBinding.myHandlers = myHandlersListener
通过这种方式,它可以完美运行,您可以按照 Android 团队提供的指南进行操作: https://developer.android.com/topic/libraries/data-binding/expressions#method_references