11

I am going to animate text size change using MotionLayout.

I do the following for start state

<CustomAttribute
    motion:attributeName="textSize"
    motion:customDimension="16sp" />

And the following for end state

<CustomAttribute
    motion:attributeName="textSize"
    motion:customDimension="14sp" />

As a result, it looks like size is actually changing, but it's much larger than 14sp-16sp

So, how to change text size properly?

Artyom
  • 1,165
  • 14
  • 22
  • Try this : https://stackoverflow.com/questions/53603009/how-can-i-scale-textview-inside-parent-view-with-motion-layout – Rahul Khatri Nov 14 '19 at 12:21

5 Answers5

12

Try this

<CustomAttribute
    motion:attributeName="textSize"
    motion:customFloatValue="14" />
Sk Suraj
  • 500
  • 2
  • 15
8

Try animating font size using scale attribute as it is Double type instead of textSize (Integer). Animation will be cleaner because Double scales smoother.

<ConstraintSet 
        android:id="@id/start">
    <Constraint
        android:id="@id/element"   
        android:scaleX="1.0"
        android:scaleY="1.0"/>
</ConstraintSet>

<ConstraintSet
        android:id="@id/end">
    <Constraint
        android:id="@id/element"   
        android:scaleX="0.5"
        android:scaleY="0.5"/>
</ConstraintSet>
Irwin Nawrocki
  • 337
  • 4
  • 7
  • 3
    This solution is much more reliable than animating `textSize`. First of all text size values set with `setTextSize` don't match those set with `android:textSize`. Secondly, by setting `android:transformPivotX` and `android:transformPivotY`, you can place text scaling pivot where you need it. – Slav Nov 18 '20 at 14:41
  • 3
    glad you shared this approach, the other ans like using **motion:customFloatValue** gave a weird flicker and some alphabets goes missing during transition if i make fast up and down drag – MDT Aug 02 '21 at 17:50
  • Scale doesn't affect the layout, including the size of `wrap_content` `MotionLayout`. – Agent_L Dec 29 '21 at 12:16
5

The above answer is correct. Because it is a CustomAttribute with the value as customFloatValue, you must pass in a float, not a scalable pixel dimension.

However, the custom attribute textSize when used on a TextView simply calls setTextSize which as you can see here interprets the float given as a scalable type so it will set it to sp automatically! Tada!

kjanderson2
  • 1,209
  • 12
  • 23
0

Use "motion:customDimension" for change textSize. Below file is scene.xml

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

    <Transition
        motion:constraintSetEnd="@+id/end"
        motion:constraintSetStart="@+id/start"
        motion:duration="2000">
        <OnSwipe
            motion:dragDirection="dragDown"
            motion:moveWhenScrollAtTop="true"
            motion:touchAnchorSide="bottom"
            motion:touchRegionId="@+id/ivExpand" />
    </Transition>

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

    <Constraint
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <CustomAttribute
                motion:attributeName="textSize"
                motion:customDimension="10sp" />

        </Constraint>

 </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
 <Constraint
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <CustomAttribute
                motion:attributeName="textSize"
                motion:customDimension="5sp" />

        </Constraint>
    </ConstraintSet>

Add scene.xml (scene description file) in mainActivity.xml

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

 <androidx.appcompat.widget.AppCompatTextView
                android:id="@+id/tvName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@android:color/black"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"/>
</<androidx.constraintlayout.motion.widget.MotionLayout>
Chirag Prajapati
  • 25
  • 1
  • 1
  • 7
0

I struggled at the same thing and managed to get it worked. If you are using motion editor, chances are the start constraintSet is based on the layout. You have to manually specify the textSize on the start constraintSet:

<ConstraintSet android:id="@+id/start">
    <Constraint
        android:id="@+id/tv_car_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@id/iv_car"
        app:layout_constraintStart_toStartOf="parent">
        <CustomAttribute
            app:attributeName="textSize"
            app:customFloatValue="30"/>
    </Constraint>
</ConstraintSet>

And finally, for the end constraintSet:

<ConstraintSet android:id="@+id/end">
    <Constraint
        android:id="@+id/tv_car_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintBottom_toBottomOf="@id/iv_car"
        app:layout_constraintStart_toStartOf="parent">
        <CustomAttribute
            app:attributeName="textSize"
            app:customFloatValue="15"/>
    </Constraint>
</ConstraintSet>
Jim Ovejera
  • 739
  • 6
  • 10