简体   繁体   English

如何在Android中使用DataBinding在XML视图中获取选定的值

[英]How to get the selected value on view in xml using dataBinding in android

<TextView
        android:id="@+id/tv_login_or_register"
        android:layout_width="305dp"
        android:layout_height="45dp"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="28dp"
        android:background="@drawable/login_tv_bg"
        android:onClick="@{()->presenter.login(tabLoginPassword.selected)}"
        android:gravity="center"
        android:text="login"
        android:textColor="#000000"
        android:textSize="16sp" />

tabLoginPassword is a view extends TextView. tabLoginPassword是扩展TextView的视图。 The expression ()->presenter.login(tabLoginPassword.selected) turns out to be wrong,so i want to know how to get the same value as view.isSelected(),thanks! 表达式()-> presenter.login(tabLoginPassword.selected)原来是错误的,所以我想知道如何获得与view.isSelected()相同的值,谢谢!

The attribute android:selected doesn't support two-way binding because there is no event listener in View that notifies when that value changes. android:selected属性不支持双向绑定,因为View中没有事件侦听器会在该值更改时通知。 If the android:selected property were already data bound, then you wouldn't have to do anything because your expression would pick up the value from the bound expression. 如果android:selected属性已经绑定了数据,则您无需执行任何操作,因为您的表达式将从绑定的表达式中获取值。 That is, if you used an expression like this: 也就是说,如果您使用这样的表达式:

<EditText android:id="@+id/tabLoginPassword"
          android:selected="@{model.passwordSelected}" .../>

Then your chained binding expression would work and be the equivalent of this: 然后,您的链式绑定表达式将起作用,并且等效于此:

<TextView
    android:id="@+id/tv_login_or_register"
    android:onClick="@{()->presenter.login(model.passwordSelected)}"
    .../>

I don't know how your isSelected() changes, so I expect that you have code other than data binding that sets it -- perhaps accessibility or internal code. 我不知道您的isSelected()是如何变化的,所以我希望您有除设置它的数据绑定以外的其他代码-可能是可访问性或内部代码。 To handle two-way data binding, you should add an event listener for the android:selected attribute and notify when the value changes. 要处理双向数据绑定,您应该为android:selected属性添加事件监听器,并在值更改时通知。

You should use this medium article as a guide . 您应该使用这篇中等文章作为指导

Here's a shortened version, but you can tailor it how you like. 这是一个简化的版本,但是您可以根据自己的喜好对其进行定制。 Definitely look at the article. 绝对看看这篇文章。

Add an event listener for when the selected value changes: 为所选值更改时添加事件侦听器:

public interface OnSelectedChangedListener {
    void selectedChanged();
}

Extend your View class to support the listener: 扩展View类以支持侦听器:

public class TabLoginPassword extends EditText {
    private OnSelectedChangedListener mOnSelectedChangedListener;

    public void setOnSelectedChangedListener(OnSelectedChangedListener listener) {
      mOnSelectedChangedListener = listener;
    }

    @Override
    protected void dispatchSetSelected(boolean selected) {
        super.dispatchSetSelected(selected);
        if (mOnSelectedChangedListener != null) {
            mOnSelectedChangedListener.selectedChanged();
        }
    }

    //...
}

Add an BindingAdapter for the event listener: 为事件侦听器添加BindingAdapter:

@BindingAdapter("android:selectedAttrChanged")
public static void setSelectedChanged(TabLoginPassword view,
          final InverseBindingListener inverseBindingListener) {
    OnSelectedChangedListener listener = null;
    if (inverseBindingListener != null) {
        listener = new OnSelectedChangedListener() {
            @Override
            public void selectedChanged() {
                inverseBindingListener.onChange();
            }
        }
    }
    view.setOnSelectedChangedListener(listener);
}

Because dispatchSetSelected() isn't called unless there is a change in the selected value, you don't need to worry about infinite loops and don't have to create a BindingAdapter for the value. 因为除非所选值发生更改,否则不会调用dispatchSetSelected() ,因此您无需担心无限循环,也不必为该值创建BindingAdapter。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM