Search code examples
androidandroid-motionlayout

android motionLayout's CustomAttribute - how to specifiy a background color from drawable resources


IN androids motionLayout i need to change the color while the view transitions. but it seems to not take resource links such as "@drawable/myshape". it wants raw values like "#FFFFFF". here is what i have done so far:

    <?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Transition
        android:id="@+id/transition"
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@id/start"
        app:motionInterpolator="linear"
        app:moveWhenScrollAtTop="true">

    </Transition>

    <ConstraintSet android:id="@+id/start">

        <Constraint
            android:id="@+id/spaceShip"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:alpha="1"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" >

<!--            <CustomAttribute-->
<!--                app:attributeName="backgroundColor"-->
<!--               app:customColorValue="@drawable/space_spaceShip_bg" />-->  

//the above code does not work. it wants a raw value, how to specify it from a drawable as i created a custom background shape already for my background.

        </Constraint>

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">

        <Constraint
            android:id="@+id/spaceShip"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:alpha="0"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" >

            <CustomAttribute
                app:attributeName="backgroundColor"
                app:customColorValue="#FFFFFF" />    //also here how to specify @color/white instead of raw value
        </Constraint>

    </ConstraintSet>

</MotionScene>

Solution

  • it seems the way to do this is to find a property of some view that has a setter that scales from 0 to 1. the [imageFilterView][1] class is one such. it has a property called [setcrossfade][2]

    so my motionlayout can look like this:

        <?xml version="1.0" encoding="utf-8"?>
    <MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <Transition
            android:id="@+id/transition"
            app:constraintSetEnd="@id/end"
            app:constraintSetStart="@id/start">
    
        </Transition>
    
        <ConstraintSet android:id="@+id/start">
    
            <Constraint
                android:id="@+id/myview"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:alpha="1"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" >
    
                <CustomAttribute
                    app:attributeName="crossfade"
                    app:customFloatValue="0" />
    
            </Constraint>
    
        </ConstraintSet>
    
        <ConstraintSet android:id="@+id/end">
    
            <Constraint
                android:id="@+id/myview"
                android:layout_width="0dp"
                android:layout_height="0dp"
                android:alpha="0"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent" >
    
                <CustomAttribute
                    app:attributeName="crossfade"
                    app:customFloatValue="1" />
    
            </Constraint>
    
        </ConstraintSet>
    
    </MotionScene>
    

    and in our layout file we can do this:

     <androidx.constraintlayout.motion.widget.MotionLayout
        android:id="@+id/ml"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        android:layout_gravity="bottom"
        app:layoutDescription="@xml/motion_scene">
    
        <androidx.constraintlayout.utils.widget.ImageFilterView
            android:id="@+id/myview"
            android:layout_width="0dp"
            android:layout_height="0dp"
    
            android:src="@drawable/bg1"
            app:altSrc="@drawable/bg2"
    
            android:background="@drawable/bg1"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintBottom_toBottomOf="parent"
            />
    
    </androidx.constraintlayout.motion.widget.MotionLayout>
    

    transition it how you want ..manually or using a swipe in the motion layout file. anyway afterwards, it will fade out one drawable and fade in another one. exactly what i wanted. [1]: https://developer.android.com/reference/androidx/constraintlayout/utils/widget/ImageFilterView [2]: https://developer.android.com/reference/androidx/constraintlayout/utils/widget/ImageFilterView#setCrossfade(float)