【问题标题】:Horizontally Align Two TextViews in MotionLayout在 MotionLayout 中水平对齐两个 TextView
【发布时间】:2019-12-02 11:45:00
【问题描述】:

我正在尝试构建一个运动场景,其中两个文本视图以折叠工具栏样式从展开状态过渡到向上拖动时的折叠状态。

这两个文本视图分别位于屏幕的左侧和右侧,并有一些边距,并且应该彼此水平对齐。

左侧的第一个 textview 与左侧的后退按钮箭头有一个边距,需要在 parent 中左对齐。

右侧的第二个文本视图在其右侧和父级末尾之间有一个边距。

两个文本视图需要有一个文本大小平滑转换的过渡。

我怎样才能达到同样的效果?

运动布局:

<androidx.constraintlayout.motion.widget.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">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="0dp"
        android:layout_height="0dp"
        android:clipToPadding="false"
        android:paddingTop="10dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/space"/>

    <View
        android:id="@+id/space"
        android:layout_width="0dp"
        android:layout_height="110dp"
        android:background="@color/white"
        android:fitsSystemWindows="true"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:foreground="?attr/selectableItemBackground"
        android:padding="20dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_view_1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="80dp"
        android:layout_marginEnd="10dp"
        android:elevation="0dp"
        android:textAlignment="viewStart"
        android:textColor="@color/text_black"
        android:text="text view 1"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="@id/space"
        app:layout_constraintEnd_toStartOf="@id/text_view_2"
        app:layout_constraintStart_toStartOf="parent" />

    <TextView
        android:id="@+id/text_view_2"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="10dp"
        android:layout_marginEnd="20dp"
        android:elevation="0dp"
        android:textAlignment="viewEnd"
        android:textColor="@color/text_black"
        android:text="text view 2"
        android:textSize="24sp"
        app:layout_constraintBottom_toBottomOf="@id/space"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/text_view_1" />

</androidx.constraintlayout.motion.widget.MotionLayout>

动态场景:

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

    <Transition
        app:constraintSetEnd="@id/state_collapsed"
        app:constraintSetStart="@id/state_expanded">

        <OnSwipe
            app:dragDirection="dragUp"
            app:touchAnchorId="@id/recyclerview"
            app:touchAnchorSide="top" />

        <KeyFrameSet>
            <KeyAttribute
                app:framePosition="50"
                app:motionTarget="@id/text_view_1">
                <CustomAttribute
                    app:attributeName="textSize"
                    app:customFloatValue="20" />
            </KeyAttribute>

            <KeyAttribute
                app:framePosition="50"
                app:motionTarget="@id/text_view_2">
                <CustomAttribute
                    app:attributeName="textSize"
                    app:customFloatValue="20" />
            </KeyAttribute>
        </KeyFrameSet>

    </Transition>

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

        <Constraint android:id="@id/back">

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="6dp" />

        </Constraint>

        <Constraint
            android:id="@id/space"
            android:layout_height="?attr/actionBarSize"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="6dp" />

        </Constraint>

        <Constraint
            android:id="@id/text_view_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="80dp"
            android:textAlignment="viewStart"
            app:layout_constraintBottom_toBottomOf="@id/back"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@id/back">

            <CustomAttribute
                app:attributeName="textSize"
                app:customFloatValue="16" />

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="6dp" />

        </Constraint>

        <Constraint
            android:id="@id/text_view_2"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp"
            android:textAlignment="viewEnd"
            app:layout_constraintBottom_toBottomOf="@id/text_view_1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintTop_toTopOf="@id/text_view_1">

            <CustomAttribute
                app:attributeName="textSize"
                app:customFloatValue="16" />

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="6dp" />

        </Constraint>

    </ConstraintSet>

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

        <Constraint android:id="@id/back">

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="0dp" />

        </Constraint>

        <Constraint
            android:id="@id/space"
            android:layout_height="110dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="0dp" />

        </Constraint>

        <Constraint
            android:id="@id/text_view_1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="80dp"
            app:layout_constraintBottom_toBottomOf="@id/space"
            app:layout_constraintEnd_toStartOf="@id/text_view_1"
            app:layout_constraintStart_toStartOf="parent">

            <CustomAttribute
                app:attributeName="textSize"
                app:customFloatValue="24" />

            <CustomAttribute
                app:attributeName="elevation"
                app:customDimension="0dp" />

        </Constraint>

    </ConstraintSet>

</MotionScene>

【问题讨论】:

  • 考虑使用CustomAttribute:developer.android.com/reference/android/support/constraint/… 这是一篇对视图颜色进行此操作的文章:medium.com/google-developers/… 对文本大小进行一些调整,你应该会很好!跨度>
  • @Marijan 感谢您的回复。我已经添加了我想要改进的运动场景和运动布局,但是在第一个小的向上拖动运动中,text_view_2 的行为不规律并消失,直到它到达动画开始或结束位置。连续向上/淹没拖动不会显示相同的行为。

标签: android android-layout android-constraintlayout android-motionlayout


【解决方案1】:

我在我的项目中也有类似的目标,我在约束中使用了android:scaleXandroid:scaleY 属性,因为使用CustomAttribute 更改textSize attr 并不顺利。当您使用android:scaleXandroid:scaleY 时,视图将在其中心使用枢轴进行缩放。所以你可能会遇到对齐问题。您必须设置 android:transformPivotX="..."android:transformPivotY="..." 才能更改默认行为。结果,我的情况是这样的:

我要动画的TextView:

<TextView
                android:id="@+id/title_tv"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:text="Text"
                android:transformPivotX="0sp"
                android:transformPivotY="24dp"/>

运动场景:

<?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/collapsed"
        motion:constraintSetStart="@id/expanded">

        <OnSwipe
            motion:dragDirection="dragUp"
            motion:touchAnchorId="@+id/viewpager"
            motion:touchAnchorSide="top" />

    </Transition>

    <ConstraintSet android:id="@+id/expanded">
        <Constraint
            android:id="@id/toolbar_image_iv"
            android:layout_height="200dp"
            ...>
            <CustomAttribute
                motion:attributeName="imageAlpha"
                motion:customIntegerValue="255" />
        </Constraint>
        <Constraint
            android:id="@id/title_tv"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:scaleX="1.0"
            android:scaleY="1.0"
            ...>
        </Constraint>
    </ConstraintSet>

    <ConstraintSet android:id="@+id/collapsed">
        <Constraint
            android:id="@id/toolbar_image_iv"
            android:layout_height="?attr/actionBarSize"
            ...>
            <CustomAttribute
                motion:attributeName="imageAlpha"
                motion:customIntegerValue="0" />
        </Constraint>
        <Constraint
            android:id="@id/title_tv"
            android:layout_width="wrap_content"
            android:layout_height="?attr/actionBarSize"
            android:scaleX="0.667"
            android:scaleY="0.667"
            ...>
        </Constraint>

    </ConstraintSet>

</MotionScene>

【讨论】:

    【解决方案2】:

    尝试使用以下代码并将虚拟元素添加到回收器视图以获得预期的行为。

    运动布局:

        <?xml version="1.0" encoding="utf-8"?>
        <androidx.constraintlayout.motion.widget.MotionLayout
                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"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:showPaths="true"
                android:id="@+id/motionLayout"
                app:layoutDescription="@xml/scene01">
    
    
            <TextView
                    android:textColor="@android:color/black"
                    android:text="TextView"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/textView1"/>
            <ImageView
                    android:layout_width="40dp"
                    android:layout_height="40dp" app:srcCompat="@mipmap/ic_launcher"
                    android:id="@+id/imageView"
                    app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="24dp"
                    android:layout_marginTop="24dp" app:layout_constraintTop_toTopOf="parent"/>
            <TextView
                    android:text="TextView"
                    android:textColor="@android:color/black"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/textView2"/>
            <View android:layout_width="0dp"
                  android:layout_height="1dp"
                  android:id="@+id/view"
                  android:layout_marginTop="20dp"
                  app:layout_constraintTop_toBottomOf="@id/textView1"
                  app:layout_constraintStart_toStartOf="parent"
                  app:layout_constraintEnd_toEndOf="parent"/>
    
            <androidx.recyclerview.widget.RecyclerView android:layout_width="0dp"
                                                       android:id="@+id/recyclerview"
                                                       app:layout_constraintTop_toBottomOf="@id/view"
                                                       app:layout_constraintStart_toStartOf="parent"
                                                       app:layout_constraintEnd_toEndOf="parent"
                                                       app:layout_constraintBottom_toBottomOf="parent"
                                                       android:layout_height="0dp"/>
        </androidx.constraintlayout.motion.widget.MotionLayout>
    

    动态场景:

     <?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">
            <OnSwipe
                    motion:touchAnchorId="@+id/recyclerview"
                    motion:touchAnchorSide="top"
                    motion:dragDirection="dragUp"/>
        </Transition>
    
        <ConstraintSet android:id="@+id/start">
            <Constraint android:id="@+id/textView1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        motion:layout_constraintStart_toEndOf="@+id/imageView"
                        android:layout_marginStart="20dp" android:layout_marginTop="16dp"
                        motion:layout_constraintTop_toBottomOf="@+id/imageView">
                <CustomAttribute motion:attributeName="textSize" motion:customFloatValue="25"/>
            </Constraint>
            <Constraint
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/textView2"
                    motion:layout_constraintTop_toTopOf="@+id/textView1"
                    motion:layout_constraintEnd_toEndOf="parent"
                    android:layout_marginEnd="20dp">
                <CustomAttribute motion:attributeName="textSize" motion:customFloatValue="25"/>
            </Constraint>
        </ConstraintSet>
    
        <ConstraintSet android:id="@+id/end">
            <Constraint android:id="@+id/textView1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        motion:layout_constraintStart_toEndOf="@+id/imageView"
                        android:layout_marginStart="20dp"
                        motion:layout_constraintTop_toTopOf="@+id/imageView">
                <CustomAttribute motion:attributeName="textSize" motion:customFloatValue="15"/>
            </Constraint>
            <Constraint
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:id="@+id/textView2"
                    motion:layout_constraintTop_toTopOf="@+id/textView1"
                    motion:layout_constraintEnd_toEndOf="parent"
                    android:layout_marginEnd="20dp">
                <CustomAttribute motion:attributeName="textSize" motion:customFloatValue="15"/>
            </Constraint>
        </ConstraintSet>
    
    </MotionScene>
    

    【讨论】:

      猜你喜欢
      • 2016-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-03
      相关资源
      最近更新 更多