自定义视图上的自定义侦听器的数据绑定

fst*_*any 20 data-binding android android-databinding

我正在尝试使用新的Android数据绑定库绑定自定义视图上的事件,但遇到了问题.

这是我的自定义视图的相关部分:

public class SuperCustomView extends FrameLayout {
    private OnToggleListener mToggleListener;

    public interface OnToggleListener {
        void onToggle(boolean switchPosition);
    }

    public void setOnToggleListener(OnToggleListener listener) {
        mToggleListener = listener;
    }
    .../...
 }
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用此自定义视图并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"/>
Run Code Online (Sandbox Code Playgroud)

toggleStrokeLimitation控制器上的方法在哪里:

public void toggleStrokeLimitation(boolean switchPosition) {
    maxStrokeEnabled.set(switchPosition);
}
Run Code Online (Sandbox Code Playgroud)

编译时出现此错误:

> 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 ****
Run Code Online (Sandbox Code Playgroud)

我试过用android:onToggle而不是app:onToggle得到同样的错误.

在阅读doc绑定事件部分时,我觉得我可以将控制器上的任何方法连接到onToggle事件.

框架是否将controller.toggleStrokeLimitation方法包装成SuperCustomView.OnToggleListener?关于onClick框架提供的现有技术背后的那种魔力的暗示?

小智 24

@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;
    }
    .../...
}
Run Code Online (Sandbox Code Playgroud)

我测试代码的黑客是:

public void setOnToggleListener(final OnToggleListener listener) {
    this.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            toggle = !toggle;
            listener.onToggle(toggle);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

在我的控制器对象上:

 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

是啊!有效

或者您可以使用xml,如:

 <com.androidbolts.databindingsample.model.SuperCustomView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:onToggleListener="@{controller.toggleStrokeLimitation}" />
Run Code Online (Sandbox Code Playgroud)

现在无需添加@BindingMethods注释.

文档说: "某些属性具有不匹配名称的setter.对于这些方法,属性可以通过BindingMethods注释与setter相关联.这必须与类关联并包含BindingMethod注释,每个重命名的方法一个. "


Pha*_*inh 7

如果您按照 Java bean 格式正确定义方法名称,则您可能不需要 BindingMethods在自定义视图上监听侦听器。这是一个例子

自定义视图类

public class CustomView extends LinearLayout {
    ...
    private OnCustomViewListener onCustomViewListener;

    ...
    public void setOnCustomViewListener(OnCustomViewListener onCustomViewListener) {
        this.onCustomViewListener = onCustomViewListener;
    }


    ....
    public interface OnCustomViewListener {
        void onCustomViewListenerMethod(int aNumber);
    }
}
Run Code Online (Sandbox Code Playgroud)

XML

<...CustomView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:onCustomViewListener="@{viewModel.viewModelListenerMethod}" // or use can use app:onCustomViewListener="@{viewModel::viewModelListenerMethod}"
    />
Run Code Online (Sandbox Code Playgroud)

视图模型

public class ViewModel extends BaseObservable{

    public void viewModelListenerMethod(int aNumber){
       // handle listener here
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 很好的解决方案!如果OnCustomViewListener接口包含多个方法怎么办? (2认同)