4

I'm trying to scale a textView inside a container view. Activity uses a motion layout. I can scale the textView if I don't place it inside the container. Here is my activity layout and the motion layout description file. How can I make scaleX and scaleY work?

Activity Layout

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.MotionLayout xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/motionLayout"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@xml/motion_scene_text_size">

    <View
        android:id="@+id/button"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:background="@color/colorAccent"
        android:text="Button" />

    <android.support.constraint.ConstraintLayout
        android:id="@+id/container"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginTop="100dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

    </android.support.constraint.ConstraintLayout>

</android.support.constraint.motion.MotionLayout>

Motion scene

<?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:constraintSetStart="@+id/start"
        motion:constraintSetEnd="@+id/end"
        motion:duration="1000">
        <OnSwipe
            motion:touchAnchorId="@+id/button"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight" />
    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginStart="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="20sp"
            android:scaleX="1.0"
            android:scaleY="1.0"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@id/button"
            android:layout_width="64dp"
            android:layout_height="64dp"
            android:layout_marginEnd="8dp"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

        <Constraint
            android:id="@id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView"
            android:textSize="20sp"
            android:scaleX="2.0"
            android:scaleY="2.0"
            motion:layout_constraintBottom_toBottomOf="parent"
            motion:layout_constraintEnd_toEndOf="parent"
            motion:layout_constraintStart_toStartOf="parent"
            motion:layout_constraintTop_toTopOf="parent" />

    </ConstraintSet>

</MotionScene>
syloc
  • 4,569
  • 5
  • 34
  • 49
  • I'm not really sure of what you want to do. If you want to just change the size of the TextView but not the size of the text, just animate the width and the height. If you want to move the size of the text, try to have two different textSizes in your Constraint Set – RDO Dec 06 '18 at 10:08
  • Can you please share how you solved this issue ? – K Pradeep Kumar Reddy Jun 19 '21 at 12:11
  • @KPradeepKumarReddy Take a look at the MotionLayout.TransitionListener. Just use the onTransitionChange event and do what ever you want with the current progress value. – syloc Jun 20 '21 at 13:54
  • thanks @syloc, I tried it. When we drag the screen slowly, the animation is not looking good. Can we speed up the motion layout animation ? or Can we try nesting MotionLayout inside MotionLayout for solving this problem, instead of using MotionLayout.TransitionListener ? – K Pradeep Kumar Reddy Jun 20 '21 at 16:50
  • @KPradeepKumarReddy I don't know your use case, but maybe keyframes are what you are looking for. https://medium.com/google-developers/defining-motion-paths-in-motionlayout-6095b874d37 – syloc Jun 20 '21 at 19:10

2 Answers2

9

It's worth noting that you can only animate direct children of a MotionLayout.

If you have to use this container, you could use matchParent for the height and width of your TextView and then use AutoSizeText.

<MotionLayout
   ...>

   <ConstraintLayout
    android:id="@+id/container"
    ...>

      <TextView
       android:layout_width="matchParent"
       android:layout_height="matchParent"
       app:autoSizeTextType="uniform"
       app:autoSizeMinTextSize="20sp"
       app:autoSizeMaxTextSize="40sp"
       .../>

   </ConstraintLayout>

</MotionLayout>

In your MotionScene, change the size of the ConstraintLayout:

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

   <Constraint
    android:id="@id/container"
    android:layout_width="200dp"
    android:layout_height="200dp"
    ... />

</ConstraintSet />
jossiwolf
  • 1,865
  • 14
  • 22
  • 1
    Yes. Not being the direct child is the issue. I ended up using the progress value of motionlayout and do it programmatically. – syloc Dec 10 '18 at 10:00
  • @syloc Is there a work around for Motion Layout limitation of works only with its direct children. It does not support nested layout hierarchies or activity transitions. – K Pradeep Kumar Reddy Jun 19 '21 at 12:10
0

What worked for me was to set the HEIGHT of TextView and the TextSize, all together to resize, like :

<Transition
    motion:constraintSetEnd="@+id/end"
    motion:constraintSetStart="@+id/start" />

<ConstraintSet android:id="@+id/start">
    <Constraint android:id="@id/titleTextView">
        <Layout
            ........
            android:layout_width="match_parent"
            android:layout_height="32dp"
            .......
            />
        <CustomAttribute
            motion:attributeName="textSize"
            motion:customFloatValue="28" />
    </Constraint>
    ......
</ConstraintSet>

<ConstraintSet android:id="@+id/end">
    <Constraint android:id="@id/titleTextView">
        <Layout
            android:layout_width="match_parent"
            android:layout_height="20dp"
            ..........
        />
        <CustomAttribute
            motion:attributeName="textSize"
            motion:customFloatValue="16" />
    </Constraint>
</ConstraintSet>
Vitalie Suba
  • 147
  • 2
  • 7
  • I tried to change textSize using CustomAttribute, but this option didn't work smoothly. So I had to use android:scaleX="..." android:scaleY="..." in . – macros013 May 14 '20 at 11:16
  • @macros013 can you please post your solution? I specified, that you need mandatory to change both: size and height. – Vitalie Suba May 16 '20 at 02:36
  • I mentioned the solution in this answer https://stackoverflow.com/a/61796281/3607032 – macros013 May 18 '20 at 07:35