我刚开始玩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"和文档明确指出target和mode是的OnClick属性。但是当我使用该项目时将无法编译,mode因为在该命名空间中找不到它。
问题 3:我是否使用了正确的命名空间?
在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
我有一个 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
我正在尝试制作幻灯片动画。为此,我使用 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
我目前正在尝试使用 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) 我正在为我的页面使用 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 在同一个视图上?
谢谢
一旦运动场景结束,我在 MotionLayout 中有一个 NestedScrollView,然后 NestedScrollView 是可见的,但是当我尝试滚动视图时,没有事件会发生在 NestedScrollView。
<?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) 假设我有带有运动布局的简单 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)
(它没有做任何事情,因为我为了演示目的剥离了所有内容)。
现在,如果我尝试隐藏进度条(让我们说在视图的点击):
//主活动.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) 我正在尝试使用 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
我创建了一个简单的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)