Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I databind a ProgressBar in Android?

Is it possible to use data-binding for a SeekBar or ProgressBar in Android? I have this data element:

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

If I refer to the variable foo.bar (which is an int) in a TextField, it works as expected:

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

What I tried to do was this:

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

but it wasn't recognized. (As soon as I wrote an "@" between the quotes, it got red in the editor). Is there another way of data-binding it?

like image 233
prograde Avatar asked Jul 11 '15 18:07

prograde


People also ask

Can I use both DataBinding and ViewBinding?

There is nothing ViewBinding can do that DataBinding cannot but it costs longer build times. Remember you don't need to use both, if you are using DataBinding, there is no need adding ViewBinding.

What is difference between ProgressBar and SeekBar?

What is difference between ProgressBar and SeekBar? An example of SeekBar is your device's brightness control and volume control. Important Note: Attribute of a SeekBar are same as ProgressBar and the only difference is user determine the progress by moving a slider (thumb) in SeekBar.


2 Answers

To get the TextView to update when the SeekBar changes, bind to progress change through the android:onProgressChanged attribute. This expects a public method in the Model with the signature of SeekBarBindingAdapter.OnProgressChanged:

View

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

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

Model

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

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

In general I advice you to look at the source code for all the Adapter classes made for Data Binding. If you for instance navigate to the file SeekBarBindingAdapter.java in Android Studio (menu Navigate>File) you'll learn all the event methods you can bind to through the adapters there. This particular feature is available because Google have implemented the following adapter:

@BindingAdapter("android:onProgressChanged")
public static void setListener(SeekBar view, OnProgressChanged listener) {
    setListener(view, null, null, listener);
}
like image 136
Nilzor Avatar answered Nov 06 '22 06:11

Nilzor


Well you may need to use two-way binding like below.

Add in binding utils class

private static final String ANDROID_PROGRESS = "android:progress";

@BindingAdapter(ANDROID_PROGRESS)
public static void setSeekbarProgress(SeekBar seekBar, int progress) {
    try {
        seekBar.setProgress(progress);
    } catch (Resources.NotFoundException nfe) {
        nfe.printStackTrace();
    }
}

@InverseBindingAdapter(attribute = ANDROID_PROGRESS)
public static int getSeekbarProgress(SeekBar seekBar) {
    try {
        return seekBar.getProgress();
    } catch (Resources.NotFoundException nfe) {
        nfe.printStackTrace();
        return 0;
    }
}

Add the observable in view model

var child1Age = ObservableField(1)

In the layout

 <SeekBar
            android:id="@+id/child1_age_sb"
            style="@style/HotelChildAgeSeekBarStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="@dimen/spacing_14"
            android:progress="@={vm.child1Age}"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/childs_age_label" />

        <TextView
            android:layout_marginTop="@dimen/spacing_6"
            android:id="@+id/child1_age_value"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            app:layout_constraintTop_toBottomOf="@+id/child1_age_sb"
            app:layout_constraintLeft_toLeftOf="@id/child1_age_sb"
            app:layout_constraintRight_toRightOf="@id/child1_age_sb"
            android:text="@{String.valueOf(vm.child1Age)}"
            android:textColor="@color/black_medium"
            android:textSize="@dimen/font_14"/>
like image 27
Shahbaz Hashmi Avatar answered Nov 06 '22 07:11

Shahbaz Hashmi