2015-07-11 83 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

相關問題