标签: android-motionlayout

MotionLayout:MotionScene OnClick 覆盖 setOnClickListener

我刚开始玩MotionLayout。我定义了一个活动布局MotionLayout,使用它MotionScene来隐藏和显示视图。

MotionScene过渡看起来是这样的:

<Transition
    app:constraintSetStart="@id/collapsed"
    app:constraintSetEnd="@id/expanded">

    <OnClick app:target="@id/nextButton"  />

</Transition>
Run Code Online (Sandbox Code Playgroud)

问题是,当我以编程方式向按钮添加 ClickListener 时,什么也没有发生:

nextButton.setOnClickListener {
        //do some stuff
    }
Run Code Online (Sandbox Code Playgroud)

这个监听器被完全忽略,但每次点击都会触发转换(视图展开/折叠)。我已经看到有人扩展 MotionLayout到处理点击事件的地方,但似乎有一种更简单的方法可以为按钮添加另一个点击侦听器。

问题 1:有没有办法在 MotionLayout 转换中将 ClickListener 添加到 OnClick 的目标?

问题 2:有没有办法使转换成为一次性事件? 期望的结果是,如果单击按钮时视图折叠,则视图展开,但如果它已经展开,则它保持展开状态。

最后,我使用的命名空间"http://schemas.android.com/apk/res-auto"和文档明确指出targetmode是的OnClick属性。但是当我使用该项目时将无法编译,mode因为在该命名空间中找不到它。

问题 3:我是否使用了正确的命名空间?

android android-motionlayout

14
推荐指数
2
解决办法
8943
查看次数

MotionLayout和ConstraintLayout没有动画儿童身高

在RecyclerView中使用MotionLayouts时,我注意到如果高度发生变化,MotionLayouts将无法为其子项周围的环绕设置动画.

重现该行为的简单方法是使用以下布局:

<FrameLayout 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">

    <android.support.constraint.motion.MotionLayout
        android:id="@+id/motion_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        app:layoutDescription="@xml/scene">

        <View
            android:id="@+id/child"
            android:layout_width="0dp"
            android:layout_height="200dp"
            android:background="@color/colorAccent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>

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

</FrameLayout>
Run Code Online (Sandbox Code Playgroud)

以及与OnClick触发器关联的MotionScene:

<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="1000">

        <OnClick
            motion:target="@id/child"
            motion:mode="toggle"/>

    </Transition>

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

        <Constraint
            android:id="@id/child"
            android:layout_height="200dp"/>

    </ConstraintSet>

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

        <Constraint
            android:id="@id/child"
            android:layout_height="400dp"/>

    </ConstraintSet>

</MotionScene>
Run Code Online (Sandbox Code Playgroud)

这将产生以下结果:

行为示范

如您所见,MotionLayout的高度在过渡开始时设置为最终预期高度,使其蓝色背景可见,直到子视图完成其自身的高度过渡并完全重叠.

如果您尝试实现扩展项目动画,则在RecyclerView中会发生同样的事情.

有没有办法让MotionLayout在转换期间完全适合它的孩子的高度,或者只是太高的成本效益?

android android-transitions android-recyclerview android-constraintlayout android-motionlayout

11
推荐指数
1
解决办法
2270
查看次数

如何在 MotionLayout 中运行特定的过渡?

我有一个 MotionScene,其中有 4 个 ConstraintSet,代表屏幕的 4 个状态(加载状态),并且它们之间有 3 个转换。当我的应用程序状态从例如加载更改为处理时,我想运行转换 1 (set1 -> set2),当状态再次更改时,我想运行转换 2 (set2 -> set3)。我找不到办法做到这一点。

我接下来尝试:

设置当前转换

     motion_layout.setTransition(R.id.set1, R.id.set2)
     motion_layout.transitionToState(R.id.set2)
Run Code Online (Sandbox Code Playgroud)

只设置过渡

motion_layout.setTransition(R.id.set1)
Run Code Online (Sandbox Code Playgroud)

转换到某种状态:

motion_layout.transitionToState(R.id.set1)
Run Code Online (Sandbox Code Playgroud)

但是上述所有方法都运行我的所有集合,即使我使用 app:autoTransition="none" 。


我尝试将所有内容都放在一个 Transition 中并设置 app:progress = 0 on ,然后通过进度控制动画状态:

 motion_layout.setProgress(0.25f, 1.0f)
Run Code Online (Sandbox Code Playgroud)

它只是将所有动画运行到最后,或者我尝试过

motion_layout.progress = 0.25f
Run Code Online (Sandbox Code Playgroud)

它没有动画,它只向我显示 0.25 动画进度,没有任何动作。

如何控制动画的流向?如何运行特定的集合?使用进步会更好吗?如何解决?

PS我用

implementation 'androidx.constraintlayout:constraintlayout:2.0.0-beta7'
Run Code Online (Sandbox Code Playgroud)

animation android android-constraintlayout androidx android-motionlayout

11
推荐指数
1
解决办法
4817
查看次数

未调用 Android MotionLayout 过渡侦听器

我正在尝试制作幻灯片动画。为此,我使用 MotionLayout 和包含两个 ConstraintSet 的 MotionScene。

幻灯片动画效果很好。但是我在 LogCat 中收到一个错误:

E/MotionLayout:警告没有 app:layoutDescription 标签

view_slider.xml

<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/motion_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:layoutDescription="@xml/scene_slider"
app:showPaths="true">

<View
    android:id="@+id/btn_slide"
    android:layout_width="64dp"
    android:layout_height="64dp"
    android:background="@color/grey26" />
</androidx.constraintlayout.motion.widget.MotionLayout>
Run Code Online (Sandbox Code Playgroud)

场景滑块.xml:

<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/btn_slide"
            motion:touchAnchorSide="right"
            motion:dragDirection="dragRight"/>

    </Transition>

    <ConstraintSet android:id="@+id/start">
        <Constraint
            android:id="@+id/btn_slide"
            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" />
    </ConstraintSet>

    <ConstraintSet android:id="@+id/end">
        <Constraint
            android:id="@+id/btn_slide"
            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" />
    </ConstraintSet>

</MotionScene>
Run Code Online (Sandbox Code Playgroud)

SliderView.kt:

class SliderView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int …
Run Code Online (Sandbox Code Playgroud)

android android-layout kotlin android-transitions android-motionlayout

10
推荐指数
1
解决办法
5569
查看次数

TextView 在 MotionLayout 中的大小动画上闪烁

在此处输入图片说明

我目前正在尝试使用 MotionLayout 创建工具栏动画。一切正常,除了当 TextView 的大小增加时,以约束为中心并用高度和宽度“wrap_content”定义的 TextView 部分闪烁。如果我将 TextView 与左侧对齐,一切都会按预期进行。这是一个已知的错误还是您知道我如何解决这个问题?

布局

<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/motionLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#FF0000"
    android:fitsSystemWindows="false">

<com.google.android.material.appbar.AppBarLayout
        android:id="@+id/app_bar"
        android:layout_width="match_parent"
        android:layout_height="250dp"
        android:theme="@style/AppTheme.AppBarOverlay">

    <com.example.motionlayout.CollapsibleToolbar
            android:id="@+id/constraintToolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:minHeight="56dp"
            app:layoutDescription="@xml/scene_11_header"
            app:layout_scrollFlags="scroll|enterAlways|snap|exitUntilCollapsed">

        <de.hdodenhof.circleimageview.CircleImageView
                android:id="@+id/icon"
                android:layout_width="wrap_content"
                android:layout_height="64dp"
                android:src="@drawable/maxmustermann" />

        <TextView
                android:id="@+id/name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Marco Schlosser"
                android:textColor="#FFFFFF"/>

        <ImageView
                android:id="@+id/ivMail"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:srcCompat="@drawable/ic_mail" />

        <ImageView
                android:id="@+id/ivPhone"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                app:srcCompat="@drawable/ic_phone" />

        <ImageView
                android:id="@+id/ivInfo"
                android:layout_width="24dp"
                android:layout_height="24dp"
                app:srcCompat="@drawable/ic_info_button" />


    </com.example.motionlayout.CollapsibleToolbar>

</com.google.android.material.appbar.AppBarLayout>

<include layout="@layout/content_scrolling" />
Run Code Online (Sandbox Code Playgroud)

场景

<Transition
        app:constraintSetEnd="@id/end"
        app:constraintSetStart="@id/start"
        app:duration="1000"
        app:motionInterpolator="linear">

    <KeyFrameSet>
        <KeyPosition
                app:framePosition="30"
                app:keyPositionType="deltaRelative"
                app:motionTarget="@id/icon"
                app:percentX="0.9"
                app:percentY="0.1" /> …
Run Code Online (Sandbox Code Playgroud)

animation android flicker textview android-motionlayout

10
推荐指数
1
解决办法
1362
查看次数

MotionLayout:同一视图上的 OnSwipe 和 OnClick

我正在为我的页面使用 MotionLayout。我有两种状态,可通过视图的 OnSwipe 切换:

<Transition
    motion:constraintSetStart="@+id/start"
    motion:constraintSetEnd="@+id/end"
    motion:duration="700"
    motion:motionInterpolator="easeIn">
    <OnSwipe
        motion:dragDirection="dragUp"
        motion:touchAnchorId="@+id/view"
        motion:touchAnchorSide="bottom"
        motion:touchRegionId="@+id/view" />
</Transition>
Run Code Online (Sandbox Code Playgroud)

我还想从代码中将 OnClickListener 添加到此视图,或在 scene.xml 文件中添加新的 Transition,这将执行与 OnSwipe Transition 不同的操作,并且将使用同一视图的 OnClick 触发。但它们都阻止了 OnSwipe。那么有没有办法让 OnSwipe 和 OnClick 在同一个视图上?

谢谢

android android-constraintlayout android-motionlayout

10
推荐指数
0
解决办法
676
查看次数

如何让 NestedScrollView 在 MotionLayout 中滚动?

一旦运动场景结束,我在 MotionLayout 中有一个 NestedScrollView,然后 NestedScrollView 是可见的,但是当我尝试滚动视图时,没有事件会发生在 NestedScrollView。

需求视频

布局xml:

<?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"
app:layoutDescription="@xml/motion_scene"
tools:context=".screens.moviedetail.controller.MovieDetailFragment">

<ImageView
    android:id="@+id/movieDetailPosterImageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="@string/poster_image"
    android:scaleType="centerCrop"
    android:src="@drawable/ic_image_24px" />

<TextView
    android:id="@+id/movieDetailMovieTitleTextView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/movieTitleBackground"
    android:fontFamily="sans-serif-smallcaps"
    android:gravity="center_vertical"
    android:padding="@dimen/commonPadding"
    android:text="@string/movie_title"
    android:textColor="@android:color/white"
    android:textSize="@dimen/commonTextSize" />

<androidx.core.widget.NestedScrollView
    android:id="@+id/detailScrollView"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.LinearLayoutCompat
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:descendantFocusability="blocksDescendants"
        android:orientation="vertical">

        <TextView
            android:id="@+id/movieDetailMovieOverviewHeadTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:fontFamily="@string/movie_detail_heading_font"
            android:gravity="center_vertical"
            android:paddingStart="@dimen/commonPadding"
            android:paddingLeft="@dimen/commonPadding"
            android:paddingTop="@dimen/commonPadding"
            android:paddingEnd="@dimen/commonPadding"
            android:paddingRight="@dimen/commonPadding"
            android:text="@string/overview"
            android:textColor="@color/headTextColor"
            android:textSize="@dimen/commonTextSize" />

        <TextView
            android:id="@+id/movieDetailMovieOverviewTextView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:fontFamily="@string/movie_detail_heading_font"
            android:gravity="center_vertical"
            android:maxLines="@integer/overviewMaxLength"
            android:paddingStart="@dimen/commonPadding"
            android:paddingLeft="@dimen/commonPadding"
            android:paddingEnd="@dimen/commonPadding"
            android:paddingRight="@dimen/commonPadding"
            android:paddingBottom="@dimen/commonPadding"
            android:textColor="@color/textColor"
            android:textSize="@dimen/commonTextSize" /> …
Run Code Online (Sandbox Code Playgroud)

android android-nestedscrollview android-motionlayout

10
推荐指数
1
解决办法
2724
查看次数

MotionLayout 的孩子忽略“setVisibility”

假设我有带有运动布局的简单 UI:

// 活动_main.xml

<?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"
    android:id="@+id/motion"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layoutDescription="@transition/motion_scene"
    app:showPaths="true">

    <View
        android:id="@+id/view"
        android:layout_width="0dp"
        android:layout_height="250dp"
        android:background="#CCAA33"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        />

    <ProgressBar
        android:id="@+id/progress_bar"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="visible"
        android:progressTint="#3366CC"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        />
</androidx.constraintlayout.motion.widget.MotionLayout>
Run Code Online (Sandbox Code Playgroud)

带有运动布局场景:

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

    <Transition
            app:constraintSetStart="@id/collapsed"
            app:constraintSetEnd="@id/expanded"
            app:duration="1000">
        <OnSwipe
                app:touchAnchorId="@id/view"
                app:touchAnchorSide="top"
                app:dragDirection="dragUp" />
    </Transition>
    <ConstraintSet android:id="@+id/collapsed">

    </ConstraintSet>

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

    </ConstraintSet>
</MotionScene>
Run Code Online (Sandbox Code Playgroud)

图片1

(它没有做任何事情,因为我为了演示目的剥离了所有内容)。

现在,如果我尝试隐藏进度条(让我们说在视图的点击):

//主活动.kt

import android.content.res.ColorStateList
import android.graphics.Color
import android.os.Bundle
import android.view.View
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity


class MainActivity : AppCompatActivity() { …
Run Code Online (Sandbox Code Playgroud)

android android-motionlayout

10
推荐指数
1
解决办法
3027
查看次数

带有 MotionLayout 的 Android 折叠工具栏 - 当 RecyclerView 为空/不可滚动时禁用运动

我正在尝试使用 MotionLayout 视图来获得折叠工具栏行为。我的方法类似于这里的示例:https : //blog.stylingandroid.com/motionlayout-collapsing-toolbar-part-1/

这工作正常,但过渡也会在滑动时开始,即使 recyclerview 为空或条目少于屏幕上的条目。

如果回收器实际上能够滚动,有没有办法只启用 MotionLayout 过渡?

我的 OnSwipe 描述:

<OnSwipe
    app:dragDirection="dragUp"
    app:maxAcceleration="40"
    app:moveWhenScrollAtTop="true"
    app:touchAnchorId="@id/recycler"
    app:touchAnchorSide="top" />
Run Code Online (Sandbox Code Playgroud)

android android-toolbar android-recyclerview android-motionlayout

9
推荐指数
1
解决办法
2553
查看次数

带有EditText的运动布局会破坏动画

我创建了一个简单的MotionLayout,它几乎与协调器布局相似(动画略有不同)。
这里是这样的:

在此处输入图片说明 在此处输入图片说明

打开键盘后,在内容区域中使用(几个)EditText视图将中断MotionLayout动画。动画现在有延迟,状态不正确,UI开始冻结。任何想法如何解决这个问题? 以gif格式链接到错误

使用的版本:

com.google.android.material:material:1.2.0-alpha01
androidx.constraintlayout:constraintlayout:2.0.0-beta3
Run Code Online (Sandbox Code Playgroud)

我也可以在一个小示例应用程序中重现该行为

示例layout.xml:

<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"
app:layoutDescription="@xml/animation"
tools:showPaths="true">

<androidx.appcompat.widget.Toolbar
    android:id="@+id/customtoolbar"
    android:layout_width="match_parent"
    android:layout_height="?attr/actionBarSize"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<com.google.android.material.textview.MaterialTextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="32dp"
    android:layout_marginBottom="48dp"
    android:text="title"
    app:layout_constraintBottom_toTopOf="@+id/formLayout"
    app:layout_constraintStart_toStartOf="parent" />

<ImageView
    android:id="@+id/image"
    android:layout_width="200dp"
    android:background="#ff00ff"
    android:layout_height="200dp"
    android:scaleType="centerCrop"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:srcCompat="@drawable/ic_home_black_24dp" />


<androidx.core.widget.NestedScrollView
    android:id="@+id/formLayout"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/image">

    <LinearLayout
        android:id="@+id/formLayoutContainer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/container1"
            android:layout_width="match_parent"
            android:layout_height="200dp">

            <EditText
                android:id="@+id/container1EditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="EditText"
                android:importantForAutofill="no"
                android:inputType="text"
                android:lines="1" />
        </com.google.android.material.textfield.TextInputLayout>

        <com.google.android.material.textfield.TextInputLayout
            android:id="@+id/container2"
            android:layout_width="match_parent"
            android:layout_height="200dp">

            <EditText
                android:id="@+id/container2EditText"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" …
Run Code Online (Sandbox Code Playgroud)

android android-motionlayout

8
推荐指数
1
解决办法
190
查看次数