我可以在Android绑定一个ProgressBar吗?

是否有可能在Android中使用SeekBar或ProgressBar的数据绑定? 我有这个数据元素:

<data> <variable name="foo" type="com.example.Foo" /> </data> 

如果我在TextField中引用variablesfoo.bar(它是一个int),它将按预期工作:

 <TextView android:text="@{String.valueOf(foo.bar)}" [...] 

我试图做的是这样的:

 <SeekBar android:progress="@{foo.bar}" [...] 

但没有得到承认。 (只要我在引号之间写了一个“@”,它就会在编辑器中变成红色)。 有没有另外一种数据绑定方式呢?

Solutions Collecting From Web of "我可以在Android绑定一个ProgressBar吗?"

为了在SeekBar更改时更新TextView,通过android:onProgressChanged属性绑定到进度更改。 这需要在SeekBarBindingAdapter.OnProgressChanged签名模型中的公共方法:

视图

 <TextView android:text="{@model.seekBarValue} /> <SeekBar android:onProgressChanged="@{model.onValueChanged}" /> 

模型

 public class Model { public ObservableField<String> seekBarValue = new ObservableField<>(""); public void onValueChanged(SeekBar seekBar, int progresValue, boolean fromUser) { seekBarValue.set(progresValue + ""); } } 

一般来说,我build议您查看所有适用于数据绑定的Adapter类的源代码。 例如,如果您导航到Android Studio中的SeekBarBindingAdapter.java文件(菜单Navigate> File),您将了解可以通过适配器绑定到的所有事件方法。 这个特殊function是可用的,因为谷歌已经实施了以下适配器:

 @BindingAdapter("android:onProgressChanged") public static void setListener(SeekBar view, OnProgressChanged listener) { setListener(view, null, null, listener); } 

如果它帮助某人,这个问题出现在search很多,现在可以使用双向数据绑定。 我在下面使用了两个可绑定的值,我倾向于在XML本身中不使用显示逻辑,但是我怀疑它也可以只使用一个。

在您的ViewModel中创build可绑定的值,一个用于SeekBarseekValue ),一个用于TextViewseekDisplay

 int mSeekValue; int mSeekDisplay; @Bindable public int getSeekValue() { return mSeekValue; } public void setSeekValue(int progress) { mSeekValue = progress; notifyPropertyChanged(BR.seekValue); setSeekDisplay(progress); } @Bindable public String getSeekDisplay() { return Integer.toString(mSeekDisplay); } public void setSeekDisplay(int progress) { mSeekDisplay = progress; notifyPropertyChanged(BR.seekDisplay); } 

现在你可以将它们绑定到Widget

 <SeekBar android:id="@+id/my_seek" android:layout_width="match_parent" android:layout_height="wrap_content" android:progress="@={viewModel.seekValue}" /> <TextView android:id="@+id/my_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@{viewModel.seekDisplay}" /> 

要注意的要点是,您正在使用@={viewModel.seekValue}SeekBar使用双向数据绑定 ,这将调用您的setSeekValue(...)方法。

一个这被称为,它将更新您的TextView通过调用setSeekDisplay(...)

@George Mount是正确的,你必须在你的Model或Handler类中定义的布局xml中添加一个处理程序(不pipe你怎么称呼它)。

看看我对这个问题的答案是一个完整的例子:

Android数据绑定库的双向数据绑定

下面是这个答案的例子:

例:

 public class AmanteEditModel extends BaseObservable { private String senhaConfirm; @Bindable public String getSenhaConfirm() { return senhaConfirm; } public void setSenhaConfirm(String senhaConfirm) { this.senhaConfirm = senhaConfirm; notifyPropertyChanged(BR.senhaConfirm); } // Textwatcher Reference: http://developer.android.com/reference/android/text/TextWatcher.html public TextWatcher getMyEditTextWatcher() { return new TextWatcher() { public void afterTextChanged(Editable s) { } public void beforeTextChanged(CharSequence s, int start, int count, int after) { } public void onTextChanged(CharSequence s, int start, int before, int count) { // Important! Use the property setter, otherwhise the model won't be informed about the change. setSenhaConfirm(s); } }; } } 

在您的布局xml中将EditText更改为:

 <EditText android:id="@+id/amante_edit_senha_confirm" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:hint="Confirme a senha" android:inputType="textPassword" android:maxLines="1" android:text="@{model.senhaConfirm}" app:addTextChangeListener="@{model.myEditTextWatcher}" /> 

注意addTextChangeListener的名称空间。 这个方法可能无法通过android:命名空间,所以我使用的应用程序:在这里。 您也可以使用bind:使绑定更清晰。

所以不要错过添加

 xmlns:app="http://schemas.android.com/apk/res-auto" 

要么

 xmlns:bind="http://schemas.android.com/apk/res-auto" 

到你的XML名字空间。

此解决scheme适用于所有input控件,包含自定义,因为您在模型中提供了正确的Listener。

TextWatcher参考