我可以在Android中对ProgressBar进行数据绑定吗?

pro*_*ade 10 data-binding android android-seekbar

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

<data>
  <variable
     name="foo"
     type="com.example.Foo" />
</data>
Run Code Online (Sandbox Code Playgroud)

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

<TextView
  android:text="@{String.valueOf(foo.bar)}"
  [...]
Run Code Online (Sandbox Code Playgroud)

我试图做的是这样的:

<SeekBar
  android:progress="@{foo.bar}"
  [...]
Run Code Online (Sandbox Code Playgroud)

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

Nil*_*zor 14

要在SeekBar更改时更新TextView,请通过android:onProgressChanged属性绑定到进度更改.这期望Model中的公共方法具有以下签名SeekBarBindingAdapter.OnProgressChanged:

视图

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

<SeekBar
    android:onProgressChanged="@{model.onValueChanged}" />
Run Code Online (Sandbox Code Playgroud)

模型

public class Model {
    public ObservableField<String> seekBarValue = new ObservableField<>("");

    public void onValueChanged(SeekBar seekBar, int progresValue, boolean fromUser) {
        seekBarValue.set(progresValue + "");
    }
}
Run Code Online (Sandbox Code Playgroud)

一般来说,我建议您查看为数据绑定所做的所有Adapter类的源代码.例如,如果您导航到SeekBarBindingAdapter.javaAndroid Studio中的文件(菜单导航>文件),您将学习可以通过适配器绑定到的所有事件方法.由于Google已实施以下适配器,因此可以使用此特定功能:

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


Kir*_*irk 5

万一它对某人有帮助,这个问题会在搜索中出现很多,现在可以使用双向数据绑定来完成。我在下面使用两个可绑定值,我倾向于在XML本身中不希望使用任何显示逻辑,但是我怀疑它也可以只使用一个。

ViewModel中创建可绑定值,其中一个用于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);
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以将它们绑定到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}" />
Run Code Online (Sandbox Code Playgroud)

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

一个叫做,它将TextView通过调用来更新setSeekDisplay(...)


Jür*_*ann 2

@George Mount 是正确的,您必须在布局 xml 中添加一个处理程序,该处理程序在您的 Model 或 Handler 类(无论您如何称呼它)中定义。

看看我对这个问题的回答,了解一个完整的例子:

使用 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);
            }
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

在布局 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}"
    />
Run Code Online (Sandbox Code Playgroud)

留意addTextChangeListener的命名空间。此方法可能无法通过 android: 命名空间使用,因此我在这里使用 app: 。您还可以使用bind:使绑定更加清晰。

所以不要错过添加

xmlns:app="http://schemas.android.com/apk/res-auto"
Run Code Online (Sandbox Code Playgroud)

或者

xmlns:bind="http://schemas.android.com/apk/res-auto"
Run Code Online (Sandbox Code Playgroud)

到您的 XML 命名空间。

如果您在模型中提供了正确的侦听器,则此解决方案适用于所有输入控件(包括自定义控件)。

文本观察器参考