Gob*_*ber 44 android android-edittext android-databinding
我已经实现了新的Android数据绑定,并在实现后意识到它不支持双向绑定.我试图手动解决这个问题,但我很难找到一个在绑定到EditText时使用的好解决方案.在我的布局中,我有这样的观点:
<EditText
android:id="@+id/firstname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords|textNoSuggestions"
android:text="@{statement.firstName}"/>
Run Code Online (Sandbox Code Playgroud)
另一种观点也显示了结果:
<TextView
style="@style/Text.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{statement.firstName}"/>
Run Code Online (Sandbox Code Playgroud)
在我的片段中,我创建了这样的绑定:
FragmentStatementPersonaliaBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_statement_personalia, container, false);
binding.setStatement(mCurrentStatement);
Run Code Online (Sandbox Code Playgroud)
这样可以将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);
}
}
Run Code Online (Sandbox Code Playgroud)
这样做效果更好,但每次我写一封信时,GUI都会更新,因为编辑光标会移到前面.
欢迎大家提出意见
Gob*_*ber 83
编辑04.05.16:Android数据绑定现在支持自动双向绑定!简单地替换:
android:text="@{viewModel.address}"
Run Code Online (Sandbox Code Playgroud)
有:
android:text="@={viewModel.address}"
Run Code Online (Sandbox Code Playgroud)
例如,在EditText中,您将获得双向绑定.确保您更新到最新版本的Android Studio/gradle/build-tools以启用此功能.
(以前的答案):
我尝试了Bhavdip Pathar的解决方案,但这无法更新我绑定到同一个变量的其他视图.我通过创建自己的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);
}}
Run Code Online (Sandbox Code Playgroud)
使用此解决方案,您可以以任何方式更新模型(TextWatcher,OnTextChangedListener等),并为您处理无限更新循环.使用此解决方案,模型设置器可以简单地实现为:
public void setFirstName(String firstName) {
this.firstName = firstName;
notifyPropertyChanged(BR.firstName);
}
Run Code Online (Sandbox Code Playgroud)
这样可以减少模型类中的代码(您可以将侦听器保留在Fragment中).
我将不胜感激任何评论,改进或其他/更好的解决方案
Jer*_*all 19
使用gradle插件2.1+时,Android Studio 2.1+现在支持此功能
只需将EditText上的文本属性从改变@{}到@={}这样的:
<EditText
android:id="@+id/firstname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textCapWords|textNoSuggestions"
android:text="@={statement.firstName}"/>
Run Code Online (Sandbox Code Playgroud)
有关详细信息,请参阅:https://halfthought.wordpress.com/2016/03/23/2-way-data-binding-on-android/
@Gober android数据绑定支持双向绑定.因此,您无需手动进行.当您尝试将OnTextChanged-listener放在editText上时.它应该更新模型.
我尝试在editText上放置一个OnTextChanged-listener并更新模型.这创建了一个循环杀死我的应用程序(模型更新更新GUI,调用textChanged时间无穷大).
值得注意的是,实现双向绑定的绑定框架通常会为您进行此检查...
以下是修改后的视图模型示例,如果更改源自观察程序,则不会引发数据绑定通知:
让我们创建一个SimpleTextWatcher,它只需要覆盖一个方法:
public abstract class SimpleTextWatcher implements TextWatcher {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
onTextChanged(s.toString());
}
public abstract void onTextChanged(String newValue);
}
Run Code Online (Sandbox Code Playgroud)
接下来,在视图模型中,我们可以创建一个公开观察者的方法.观察程序将配置为将更改的控件值传递给视图模型:
@Bindable
public TextWatcher getOnUsernameChanged() {
return new SimpleTextWatcher() {
@Override
public void onTextChanged(String newValue) {
setUsername(newValue);
}
};
}
Run Code Online (Sandbox Code Playgroud)
最后,在视图中我们可以使用addTextChangeListener将观察者绑定到EditText:
<!-- most attributes removed -->
<EditText
android:id="@+id/input_username"
android:addTextChangedListener="@{viewModel.onUsernameChanged}"/>
Run Code Online (Sandbox Code Playgroud)
以下是解决通知无限的视图模型的实现.
public class LoginViewModel extends BaseObservable {
private String username;
private String password;
private boolean isInNotification = false;
private Command loginCommand;
public LoginViewModel(){
loginCommand = new Command() {
@Override
public void onExecute() {
Log.d("db", String.format("username=%s;password=%s", username, password));
}
};
}
@Bindable
public String getUsername() {
return this.username;
}
@Bindable
public String getPassword() {
return this.password;
}
public Command getLoginCommand() { return loginCommand; }
public void setUsername(String username) {
this.username = username;
if (!isInNotification)
notifyPropertyChanged(com.petermajor.databinding.BR.username);
}
public void setPassword(String password) {
this.password = password;
if (!isInNotification)
notifyPropertyChanged(com.petermajor.databinding.BR.password);
}
@Bindable
public TextWatcher getOnUsernameChanged() {
return new SimpleTextWatcher() {
@Override
public void onTextChanged(String newValue) {
isInNotification = true;
setUsername(newValue);
isInNotification = false;
}
};
}
@Bindable
public TextWatcher getOnPasswordChanged() {
return new SimpleTextWatcher() {
@Override
public void onTextChanged(String newValue) {
isInNotification = true;
setPassword(newValue);
isInNotification = false;
}
};
}
}
Run Code Online (Sandbox Code Playgroud)
我希望这是你正在寻找的,当然可以帮助你.谢谢
| 归档时间: |
|
| 查看次数: |
30018 次 |
| 最近记录: |