使用 Data Binding 在自定义视图中调用自定义方法

3
使用数据绑定,我该如何在自定义视图中引用自定义方法? 我正试图在我的自定义视图内设置监听器...
public class MyCustomView extends LinearLayout {

    //...view init stuff

    private VisibilityListener mListener;

    public void setVisibilityListener(VisibilityListener listener) {
        mListener = listener;
    }

    public interface VisibilityListener {
        void onVisibilityChanged(boolean isVisible);
    }
}

public class MainActivity extends AppCompatActivity implements VisibilityListener {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate();

        MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);

        // What I'm trying to accomplish...
        binding.myCustomView.setVisibilityListener(this);
    }
}

binding.myCustomView.setVisibilityListener(this); - 你试过了吗?有没有出现错误?我可以看到在我的自定义视图中声明的方法。 - yennsarah
2个回答

2
您IP地址为146.190.162.183,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。
public class ColorPicker extends View {

    private ArrayList<OnColorChangeListener> mColorChangeListeners = new ArrayList<>();
    private int mColor;

    public ColorPicker(Context context) {
        super(context);
    }

    public ColorPicker(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public ColorPicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
    public ColorPicker(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    public void setColor(int color){
        mColor = color;
        setBackgroundColor(mColor);
        if (mColorChangeListeners != null && !mColorChangeListeners.isEmpty()){
            for (OnColorChangeListener onColorChangeListener: mColorChangeListeners) {
                onColorChangeListener.onColorChangeListener(this,mColor);
            }
        }
    }

    public int getColor() {
        return mColor;
    }

    public void removeListener(OnColorChangeListener oldListener) {
        mColorChangeListeners.remove(oldListener);
    }

    public void addListener(OnColorChangeListener newListener) {
        mColorChangeListeners.add(newListener);
    }

    public interface OnColorChangeListener {
        void onColorChangeListener(ColorPicker colorPicker, int newColor);
    }
}

BindingAdapter:

@BindingAdapter(value={"event:onColorChange", "colorAttrChanged"}, requireAll = false)
    public static void setColorChangeListener(ColorPicker view,
                                              final ColorPicker.OnColorChangeListener onColorChangeListener,
                                              final InverseBindingListener inverseBindingListener) {

        ColorPicker.OnColorChangeListener newListener;
        if (inverseBindingListener == null) {
            newListener = onColorChangeListener;
        } else {
            newListener = new ColorPicker.OnColorChangeListener() {
                @Override
                public void onColorChangeListener(ColorPicker colorPicker,
                                          int newColor) {
                    if (onColorChangeListener != null) {
                        onColorChangeListener.onColorChangeListener(colorPicker,
                                newColor);
                    }
                    inverseBindingListener.onChange();
                }
            };
        }

        ColorPicker.OnColorChangeListener oldListener =
                ListenerUtil.trackListener(view, newListener,
                        R.id.onColorChangedListner);

        if (oldListener != null) {
            view.removeListener(oldListener);
        }

        if (newListener != null) {
            view.addListener(newListener);
        }
    }

XML:

<variable
            name="eventCallBack"
            type="bytes.wit.databinding.HomeActivity.EventHandler"/>

<bytes.wit.databinding.ColorPicker
            android:id="@+id/color_picker"
            android:layout_width="0dp"
            android:layout_height="24dp"
            app:color="@={placeModel.color}"
            app:onColorChange="@{(v, color) -> eventCallBack.onColorChanged(placeModel.color)}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

事件处理程序

public class EventHandler{
        public void onColorChanged(int color){
            Toast.makeText(HomeActivity.this,"Color "+color,Toast.LENGTH_SHORT).show();
        }
    }

设置事件处理程序

eventHandler = new EventHandler();
binding.setEventCallBack(eventHandler);

2
这段代码几乎是从George Mount的博客文章关于双向数据绑定中精确复制过来的,以防您需要更多信息。 :) - yennsarah

1
你可以通过在布局中使用带有ID的自定义视图来实现这一点。
<package.of.MyCustomView
        android:id="@+id/my_custom_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

这样的数据绑定将定义一个类型为MyCustomView的成员myCustomView,因此您可以在其上简单调用setVisibilityListener()
binding.myCustomView.setVisibilityListener(this);

这实际上是我现在正在尝试的,但该方法不可用。 - Psest328
那么,也许您可以发布您的XML和生成的绑定类的相关部分。还有可能是错误信息。 - tynn
我现在正在使用手机。一个半小时后回家后会更新......没有错误消息,只是不认识该方法。 - Psest328
1
这最终是正确的!当我在xml中引用我的自定义视图时,包名中有一个拼写错误。谢谢 :) - Psest328

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接