2015-07-11 57 views
9

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

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

如果我指的是可变foo.bar(这是一个int)在一个文本字段,它按预期工作:

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

我试图做的是这个:

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

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

+1

嗯,它应该工作。它可能是一个IDE突出的错误。你尝试编译? – yigit

+0

今天我学到了,我应该总是试着编译:)它的工作原理!谢谢,yigit! – prograde

+0

但是,嗯,它会调用foo.getBar()方法将它自己设置在正确的位置。但它似乎永远不会调用foo.setBar()方法,所以在我的代码中永远不会更新该值。它仍然需要一个SeekBarChangeListener,或者什么? – prograde

回答

2

@George Mount是正确的,您必须在您的模型或处理程序类(无论您称之为)中定义的布局xml中添加处理程序。

看看我的回答对这个问题的一个羽翼丰满的例子:

Two way databinding with Android Databinding Library

下面是这个问题的答案的例子:

例子:

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:命名空间获得,所以我正在使用app:here。您也可以使用bind:使绑定更清晰。

所以千万不要错过

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

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

添加到您的XML命名空间。

此解决方案适用于所有输入控件,包含自定义,因为您在模型中提供了正确的听众。

TextWatcher Reference

8

为了让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 + ""); 
    } 
} 

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

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

在情况下,它可以帮助别人,这个问题在搜索自带了很多,这现在可以使用双向数据绑定来完成。我在下面使用两个可绑定的值,我倾向于不喜欢XML本身的显示逻辑,但我怀疑它也可以只用一个。

视图模型,一个用于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},这将打电话给你setSeekValue(...)方法数据绑定在SeekBar

一个这就是所谓的,它会更新你的TextView致电setSeekDisplay(...)

+0

+1表示@ = {}表示法。您也可以使用单个属性seekValue并在TextView上使用@ {Integer.toString(viewModel.seekValue)}。 – josmith42

相关问题