android - 使用 Android 数据绑定(bind)创建双向绑定(bind)

标签 android android-edittext android-databinding

我已经实现了新的Android数据绑定(bind),实现后发现不支持双向绑定(bind)。我试图手动解决这个问题,但我很难找到一个在绑定(bind)到 EditText 时使用的好的解决方案。 在我的布局中,我有这个 View :

<EditText
android:id="@+id/firstname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords|textNoSuggestions"
android:text="@{statement.firstName}"/>

另一个 View 也在显示结果:

<TextView
style="@style/Text.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{statement.firstName}"/>

在我的 fragment 中,我创建这样的绑定(bind):

FragmentStatementPersonaliaBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_statement_personalia, container, false);
binding.setStatement(mCurrentStatement);

这有效,并将 firstName 的当前值放入 EditText。问题是如何在文本更改时更新模型。我尝试在 editText 上放置一个 OnTextChanged-listener 并更新模型。这创建了一个循环杀死我的应用程序(模型更新更新 GUI,它调用 textChanged 时间无穷大)。接下来,我尝试仅在发生真正的更改时通知:

@Bindable
public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
        boolean changed = !TextUtils.equals(this.firstName, firstName);
        this.firstName = firstName;
        if(changed) {
            notifyPropertyChanged(BR.firstName);
        }
    }

这效果更好,但每次我写信时,GUI 都会更新,并且出于某种原因,编辑光标移到了前面。

欢迎提出建议

最佳答案

编辑 04.05.16: Android数据绑定(bind)现在自动支持两种方式绑定(bind)! 只需替换:

android:text="@{viewModel.address}"

与:

android:text="@={viewModel.address}"

例如在 EditText 中,您将获得双向绑定(bind)。请务必更新到最新版本的 Android Studio/gradle/build-tools 以启用此功能。

(以前的答案):

我尝试了 Bhavdip Pathar 的解决方案,但这未能更新我绑定(bind)到同一变量的其他 View 。我通过创建自己的 EditText 以不同的方式解决了这个问题:

public class BindableEditText extends EditText{

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

public BindableEditText(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public BindableEditText(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

private boolean isInititalized = false;

@Override
public void setText(CharSequence text, BufferType type) {
    //Initialization
    if(!isInititalized){
        super.setText(text, type);
        if(type == BufferType.EDITABLE){
            isInititalized = true;
        }
        return;
    }

    //No change
    if(TextUtils.equals(getText(), text)){
        return;
    }

    //Change
    int prevCaretPosition = getSelectionEnd();
    super.setText(text, type);
    setSelection(prevCaretPosition);
}}

使用此解决方案,您可以以任何方式更新模型(TextWatcher、OnTextChangedListener 等),它会为您处理无限更新循环。有了这个解决方案,模型 setter 可以简单地实现为:

public void setFirstName(String firstName) {
    this.firstName = firstName;
    notifyPropertyChanged(BR.firstName);
}

这会减少模型类中的代码(您可以将监听器保留在 Fragment 中)。

如果对我的问题有任何意见、改进或其他/更好的解决方案,我将不胜感激

关于android - 使用 Android 数据绑定(bind)创建双向绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33362533/

相关文章:

android - Android 上使用 JSCH 的 SSH 连接、UnknownHostException

android - 如何使用 actionbarsherlock 更改操作栏的颜色

Android:EditText - 多行和 android:inputType

android - 数据绑定(bind) : set property if it isn't null

java - 发现多个文件的操作系统独立路径为 'android/databinding/DataBindingComponent.java'

android设置android可绘制颜色

android - OpenGL ES 2 - 一个大纹理图集与多个小纹理图集。什么是更好的性能明智?

Android TextView 字体大小更改后未调整大小

Android EditText 类似 Google Search EditText

Android DataBinding 3.0.1 对可观察变量的调用方法导致生成导致 NPE 的错误代码