4

I have this drawable for customize a progress bar:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
    <shape>
        <solid android:color="@color/marm_color_blue_palette_light_primary"></solid>
    </shape>
</item>
<item android:id="@android:id/secondaryProgress">
    <clip>
        <shape>
            <solid android:color="@color/marm_color_blue_palette_accent"></solid>
        </shape>
    </clip>
</item>
<item android:id="@android:id/progress">
    <clip>
        <shape>
            <solid android:color="@color/marm_color_blue_palette_accent"></solid>
        </shape>
    </clip>
</item>
</layer-list>

How can i use DataBinding to set those colors? I'm pretty new to Android Data Binding, i came from Windows Phone MVVM.

I know that, for an activity layout you have to do this way:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
    <import type="com.androidadvance.androidsurvey.R" />
    <variable
        name="dynamicUI"  type="com.example.DynamicConfigModel" />
</data>

<LinearLayout xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@{dynamicUI.mainBg, default=@color/color_palette_light_divider_text_12}"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@{dynamicUI.darkPrimary , default=@color/marm_color_blue_palette_dark_primary}"
        android:titleTextColor="@{dynamicUI.textLight, default=@android:color/white}"
        />

</LinearLayout>
</layout>

and in java

ContentLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.YOURLAYOUT);
        binding.setDynamicUI(YOURMODEL);

How to do that in a drawable or in style in general?

2 Answers 2

1

Because Databinding is basically generated code at compile time it is currently only designed for layouts. If you attempt to use it in drawables, styles, or menus it will not work.

I know it's unfortunate that the architecture is incomplete, but you'll notice whenever you add the layout tag surrounding your layout file it generates a NameOfActivityBinding class where it writes all the boilerplate code for you that manages the changing of elements. So while to us it just looks like xml is pointing to a variable, Android is still writing all the boiler plate for you.

Which isn't really much different then other frameworks other than the fact that we can see it still as it is early stages.

There are some property changed handlers you can create into custom controls and then utilize a custom control menu or other custom class to replace the class that you are assigning the drawable to. Then the custom class could leverage binding, but that opens up more work then it is to simply change the drawable content in code.

One thing I have done is monitor events on the respective item and then change the tint of the drawable like this.

   @JvmStatic
@BindingAdapter("backgroundDrawableChange")
fun backgroundDrawableChange(view: RelativeLayout, isSelected: Boolean){
    var bgDrawable: LayerDrawable = view.background as LayerDrawable
    var shape: GradientDrawable =  bgDrawable.findDrawableByLayerId(R.id.shapeId) as GradientDrawable
    shape.setColor(Color.parseColor((if (isSelected) YACustomPreference.getInstance(view.context).getPrimaryColorHex() else YACustomPreference.getInstance(view.context).getWhite())))
}

then I'll attach that to the property that I am monitoring for change.

      <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="30dp"
            android:orientation="horizontal"
            tools:visibility="gone"
            android:background="@drawable/rounded_bottom_right_button"
            app:backgroundDrawableChange="@{drawerItemModel.isSelected}"
            android:visibility="@{drawerItemModel.useRightAlignText ? View.VISIBLE : View.GONE}"
            android:gravity="center" />

This was a simple row click monitor that had user defined colors and it wasn't possible to bind the color in the drawable obviously so this was the next best thing. Hope that helps.

I know it's not exactly what you were after, but might put you on the right path at least or give you an idea.

Sign up to request clarification or add additional context in comments.

Comments

0

Few days ago i`m facing a problem of setting drawable using data-binding then i found this way, it cool easy, and works perfect, simple creating this method in BindingUtils.class

public final class BindingUtils {
    private BindingUtils() {
    }
    @BindingAdapter({"progressDrawable"})
        public static void setProgressDrawable(ProgressBar progressBar, int resource) {
            if (resource != -1)
                progressBar.setProgressDrawable(ContextCompat.getDrawable(progressBar.getContext(),resource));
        }
    }

Usage in XML:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

        <import type="android.view.View" />

        <import type="android.text.TextUtils" />

        <variable
            name="viewModel"
            type="com.home.NewViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/parent"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:alpha="0.80"
        android:clickable="true"
        android:focusable="true"
        android:gravity="center">

        <ProgressBar
            android:id="@+id/progressBar"
            style="@style/Widget.AppCompat.ProgressBar.Horizontal"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:progress="@{viewModel.uploadProgress}"
            progressDrawable="@{viewModel.progressBg}"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

ViewModel:

public class NewViewModel extends ViewModel{
    public final static short INIT_PROGRESS = 0;
    public final ObservableInt uploadProgress = new ObservableInt(INIT_PROGRESS);
    public final ObservableInt progressBg = new ObservableInt(R.drawable.bg_post_uploading_style); 
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.