カスタムビューのイベントを新しいAndroidデータバインディングライブラリでバインドしようとしていますが、問題が発生します。
これが私のカスタムビューの関連部分です:
public class SuperCustomView extends FrameLayout {
private OnToggleListener mToggleListener;
public interface OnToggleListener {
void onToggle(boolean switchPosition);
}
public void setOnToggleListener(OnToggleListener listener) {
mToggleListener = listener;
}
.../...
}
このカスタムビューを使用して、onToggle
イベントを次のようにバインドしようとしています。
<data>
<variable
name="controller"
type="com.xxx.BlopController"/>
</data>
<com.company.views.SuperCustomView
Android:layout_width="match_parent"
Android:layout_height="wrap_content"
app:onToggle="@{controller.toggleStrokeLimitation}"
app:custom_title="Blah"
app:custom_summary="Bloh"
app:custom_widget="toggle"/>
ここで、toggleStrokeLimitation
はコントローラーのメソッドです。
public void toggleStrokeLimitation(boolean switchPosition) {
maxStrokeEnabled.set(switchPosition);
}
コンパイル時にこのエラーが発生します:
> Java.lang.RuntimeException: Found data binding errors.
****/ data binding error ****msg:Cannot find the setter for attribute 'app:onToggle' with parameter type Java.lang.Object. file:/path/to/androidapp/app/src/main/res/layout/fragment_stroke.xml loc:36:35 - 36:67 ****\ data binding error ****
Android:onToggle
の代わりにapp:onToggle
を使用しようとしましたが、同じエラーが発生します。
ドキュメントのバインディングイベントセクション を読んでいると、コントローラーから任意のメソッドをonToggle
イベントに接続できるように感じます。
フレームワークはcontroller.toggleStrokeLimitation
メソッドをSuperCustomView.OnToggleListener
にラップしますか?フレームワークによって提供される既存のonClick
の背後にある魔法の種類に関するヒントはありますか?
@BindingMethods(@BindingMethod(type = SuperCustomView.class, attribute = "app:onToggle", method = "setOnToggleListener"))
public class SuperCustomView extends FrameLayout {
private OnToggleListener mToggleListener;
public interface OnToggleListener {
void onToggle(boolean switchPosition);
}
public void setOnToggleListener(OnToggleListener listener) {
mToggleListener = listener;
}
.../...
}
コードをテストするための私のハックは次のとおりです。
public void setOnToggleListener(final OnToggleListener listener) {
this.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
toggle = !toggle;
listener.onToggle(toggle);
}
});
}
そして私のコントローラーオブジェクトについて:
public class MyController {
private Context context;
public MyController(Context context) {
this.context = context;
}
public void toggleStrokeLimitation(boolean switchPosition) {
Toast.makeText(context, "Toggle" + switchPosition, Toast.LENGTH_SHORT).show();
}
}
または、次のようなxmlを使用できます。
<com.androidbolts.databindingsample.model.SuperCustomView
Android:layout_width="match_parent"
Android:layout_height="match_parent"
app:onToggleListener="@{controller.toggleStrokeLimitation}" />
@BindingMethodsアノテーションを追加する必要はありません。
メソッド名を定義した場合、カスタムビューでリスナーをリッスンする場合は必要ない場合がありますBindingMethods
follow Java Bean formatCorrectly。これが例です。
CustomViewクラス
public class CustomView extends LinearLayout {
...
private OnCustomViewListener onCustomViewListener;
...
public void setOnCustomViewListener(OnCustomViewListener onCustomViewListener) {
this.onCustomViewListener = onCustomViewListener;
}
....
public interface OnCustomViewListener {
void onCustomViewListenerMethod(int aNumber);
}
}
[〜#〜] xml [〜#〜]
<...CustomView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:onCustomViewListener="@{viewModel.viewModelListenerMethod}" // or use can use app:onCustomViewListener="@{viewModel::viewModelListenerMethod}"
/>
ViewModel
public class ViewModel extends BaseObservable{
public void viewModelListenerMethod(int aNumber){
// handle listener here
}
}