约束布局版本:2.0.0-alpha3
所以我使用 MotionLayout 我想创建类似的东西。https://blog.stylingandroid.com/motionlayout-collapsing-toolbar-part-2/
我想实现当用户进入活动ProgressBar时,当我加载数据时(需要一些时间)我想ProgressBar隐藏。
我的问题是,当我开始与 UI 交互时,ProgressBar状态被重置并再次可见
我应该怎么做才能防止 progressBar 在用户开始与之交互后开始显示?
这是一个简化版
layout file
<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/collapsing_toolbar"
tools:context=".MainActivity"
tools:showPaths="true">
<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar_image">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:layout_width="match_parent"
android:layout_height="2000dp"
android:background="#ff2"/>
</FrameLayout>
</androidx.core.widget.NestedScrollView>
<ImageView
android:id="@+id/toolbar_image"
android:layout_width="0dp"
android:layout_height="200dp"
android:background="@color/colorPrimary"
android:src="@color/colorAccent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="@+id/error"
android:text="ERROR"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
Run Code Online (Sandbox Code Playgroud)
这是布局说明 ( xml/collapsing_toolbar)
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@id/collapsed"
app:constraintSetStart="@id/expanded">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="@id/scroll_view"
app:touchAnchorSide="top"/> …Run Code Online (Sandbox Code Playgroud) 我有一个在内Fragment托管一个RecyclerView的MotionLayout。在回收器视图的顶部,我有一个可以折叠和展开的视图,所有这些都在我的运动场景中完成。它是通过单击触发的,并且响应拖动回收站视图。到目前为止,这一切都按预期进行。
现在问题来了:我想在我的应用程序中完全隐藏某些状态的折叠视图。但是,如果我设置视图的可见性或更改其高度,则在拖动recyclerview时它仍会重新显示。
因此可以完全禁用MotionLayout(锁定约束),直到再次启用它为止。禁用拖动识别器也是一种可行的解决方案。
现在使用一些简化的XML来演示这种情况。
该布局包含带有标题视图和recyclerview的运动布局
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.motion.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:id="@+id/favouritesMotionLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="@xml/favourites_motion_scene"
android:animateLayoutChanges="true">
<ImageView
android:id="@+id/headerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
...
/>
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
...
>
<pinch.nrcnext.view.scroll.NRCRecyclerView
android:id="@+id/favoritesList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.constraint.motion.MotionLayout>
Run Code Online (Sandbox Code Playgroud)
对应的动作场景:
<?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/expanded"
motion:constraintSetEnd="@id/collapsed"
motion:duration="300">
<OnSwipe
motion:touchAnchorId="@id/swipeRefreshLayout"
motion:touchAnchorSide="top"
motion:dragDirection="dragUp" />
</Transition>
<ConstraintSet android:id="@+id/expanded">
... Constraints for expanded header ...
</ConstraintSet>
<ConstraintSet android:id="@+id/collapsed">
... ... Constraints for collapsed header ...
</ConstraintSet>
</MotionScene> …Run Code Online (Sandbox Code Playgroud) 假设我们有一个BottomNavigationBar,顶部有一个FAB。使用此设置并显示小吃栏时,小吃栏应出现在BottomNavigationBar上方,并在出现/关闭时向上/向下推FAB。
这是使用CoordinatorLayout的常见方案。是否还可以使用新的MotionLayout创建此动画?
Bug跟踪器中存在一个问题,但由于OP并未明确提出问题,因此该问题已关闭(https://issuetracker.google.com/issues/112665540)
我在尝试时遇到的问题:我们无权访问Snackbar的layout-id。我们也无权访问Snackbar的常规xml,因此我们无法设置其Constraints。
更新:我知道一段代码将有助于回答这个问题。但是我想出的那段代码根本没有用。我现在指出了两个主要问题:
我不知道Snackbar的layout-id。因此,我不能在编写场景描述时使用它。
即使我可以创建一个场景描述(例如,State1:SnackBar可见,State2:Snackbar不可见)。我必须手动触发这些场景过渡。这意味着我将重新创建自己的Snackbar,而不是按预期使用原始的Snackbar。
评论: @mikejonesguy是的,我认为它们相似。不一样,但是相似。而且MotionLayout确实具有您所描述的工作:协调其子视图之间的交互。用“动画”代替“坐标”,您会明白我的意思。还可以查看OnSwipe / OnClick处理程序。MotionLayout仍然很新鲜,但我认为将来它将以ConstraintLayout替换RelativeLayout的相同方式替换CoordinatorLayout。也许我错了,也许没有...时间会证明一切。
结论: 就我而言,似乎还没有办法仅通过使用MotionLayout来实现我想要的功能。如果有一天,我将通过一个可行的示例来更新此问题。对不起,不可能的赏金... :)
android android-snackbar android-constraintlayout android-architecture-components android-motionlayout
有没有什么办法可以加速播放,当我停止中旬划动的动画MotionLayout与onSwipe过渡?目前它非常缓慢地过渡到开始或结束位置。
我尝试在回收器视图的一个项目上实现动画,自定义滑动,为此,我尝试使用 MotionLayout。实际上,如果动画的触发是单击,那么效果很好,但是当我想进行滑动时,它会干扰回收器视图的滑动。这是我的场景:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@layout/chat_item_start"
motion:constraintSetEnd="@layout/chat_item_end"
motion:duration="500">
<OnClick
motion:targetId="@+id/background"
motion:clickAction="toggle" />
<!-- <OnSwipe
motion:touchAnchorId="@+id/background"
motion:touchAnchorSide="right"
motion:dragDirection="dragLeft" /> -->
</Transition>
</MotionScene>
Run Code Online (Sandbox Code Playgroud)
看看我一开始的清单:
最后,当我点击一个项目时:
当我切换到 OnSwipe 触发器时,动画会起作用,但只有当我严格水平滑动时,如果我的手指错误地向上或向下移动一点,动画就会停止,甚至不会自行完成:
我认为问题的出现是因为回收器视图还处理滑动手势,因为当动画停止时(如果我稍微向上/向下)回收器会像平常一样移动。
如果我过多地滑动,我会收到此错误:
java.lang.NullPointerException:尝试在 androidx.constraintlayout.motion.widget.MotionLayout$MyTracker.addMovement(MotionLayout. java:985) 在 androidx.constraintlayout.motion.widget.MotionScene.processTouchEvent(MotionScene.java:1043) 在 androidx.constraintlayout.motion.widget.MotionLayout.onTouchEvent(MotionLayout.java:2992) 在 android.view.View.dispatchTouchEvent (View.java:12515)在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3024)在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2705)在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java: 3030)在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2662)在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3030)在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2662)在android。 view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3030) 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2662) 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3030) 在 android.view.ViewGroup.dispatchTouchEvent (ViewGroup.java:2662) 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3030) 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2662) 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java: 3030) 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2662) 在 android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3030) 在 android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2662) 在 com. android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:444) 在 com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829) 在 android.app.Activity.dispatchTouchEvent(Activity.java:3397)在 androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69) 在 com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:402) 在 android.view.View.dispatchPointerEvent(View.java:12754) )在 android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:5052) 在 android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4855) 在 …
android android-animation android-recyclerview android-motionlayout
我有一个运动场景,它将一些视图转换到新位置并更改一些 alpha 值。到目前为止,MotionScene 基本上是线性的,这意味着它有一个开始状态和一个结束状态。
但是我希望有两个视图比其他视图早于 alpha 0。假设在过渡的 10% 处,标题和副标题应该完全淡出。据我了解,这可以通过KeyFrameSet. 我已经做了一些工作,MotionScene但我没有看到行为有任何变化。任何帮助将不胜感激!
这是我的运动场景
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="@+id/end"
app:constraintSetStart="@+id/start"
app:duration="300">
<OnSwipe
app:dragDirection="dragDown"
app:touchAnchorId="@+id/thumbnail" />
<KeyFrameSet>
<KeyAttribute
android:alpha="1"
app:motionProgress="0"
app:motionTarget="@+id/title" />
<KeyAttribute
android:alpha="0"
app:motionProgress="10"
app:motionTarget="@+id/title" />
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="@+id/start">
<Constraint
android:id="@+id/background_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<CustomAttribute
app:attributeName="cornerRadiusDp"
app:customFloatValue="0.0" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint
android:id="@+id/background_card"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent">
<CustomAttribute
app:attributeName="cornerRadiusDp"
app:customFloatValue="16.0" />
</Constraint>
<Constraint
android:id="@+id/thumbnail"
android:layout_width="40dp"
android:layout_height="40dp"
app:layout_constraintBottom_toBottomOf="@+id/background_card"
app:layout_constraintLeft_toLeftOf="@+id/background_card"
app:layout_constraintRight_toRightOf="@+id/background_card"
app:layout_constraintTop_toTopOf="@+id/background_card" />
<Constraint …Run Code Online (Sandbox Code Playgroud) 我的 MotionLayout 中有这个转换。
<Transition
android:id="@+id/transition_validate"
motion:constraintSetEnd="@id/endRight"
motion:constraintSetStart="@id/start"
motion:duration="400"
motion:motionInterpolator="easeOut">
<OnClick
motion:clickAction="transitionToEnd"
motion:targetId="@id/trueButton" />
<OnSwipe
motion:dragDirection="dragRight"
motion:touchAnchorId="@id/card"
motion:touchRegionId="@id/card"
motion:touchAnchorSide="right" />
Run Code Online (Sandbox Code Playgroud)
中间的矩形是带有cardid 的cardView。屏幕左右按钮分别为trueButton/falseButton
我的问题是,在我添加motion:touchRegionId="@id/card"到 onSwipe 后,我不能再点击1trueButton ,即上面的部分card来启动动画(它实际上在附加的屏幕上为 false 而不是 true,但你明白了),我必须点击 3 即,该部分trueButton不在卡片上方。
你见过这样的东西吗?您知道如何限制 onSwipe 触摸card但单击按钮启动动画吗?
谢谢
我正在尝试创建一个布局,其中视图将向上滚动,但在视图内有一个组件不应滚动到视图之外并停靠在顶部,其余内容滚动到其下方,该组件将滚动直到它击中屏幕顶部。
\n\n因此,对于对接部分,我使用了运动布局,并将其限制在最终状态下的父级顶部。我在停靠的组件后面放置了一个嵌套的滚动视图。这是我的运动场景文件 -
\n\n\n\n<Transition\n android:id="@+id/scrollTransition"\n motion:constraintSetEnd="@+id/end"\n motion:constraintSetStart="@id/start"\n motion:duration="1000">\n <KeyFrameSet>\n </KeyFrameSet>\n <OnSwipe\n motion:dragDirection="dragUp"\n motion:onTouchUp="stop"\n motion:touchAnchorId="@id/merchant_details"\n motion:moveWhenScrollAtTop="true"/>\n</Transition>\n\n<ConstraintSet android:id="@+id/start">\n\n</ConstraintSet>\n\n<ConstraintSet android:id="@+id/end">\n <Constraint\n android:layout_height="wrap_content"\n motion:layout_constraintStart_toStartOf="parent"\n motion:layout_constraintEnd_toEndOf="parent"\n motion:layout_constraintBottom_toTopOf="@id/merchant_details"\n android:layout_width="match_parent"\n android:id="@+id/product_details" />\n <Constraint\n android:layout_height="wrap_content"\n motion:layout_constraintStart_toStartOf="parent"\n motion:layout_constraintEnd_toEndOf="parent"\n motion:layout_constraintTop_toTopOf="parent"\n android:layout_width="match_parent"\n android:id="@+id/merchant_details" />\n</ConstraintSet>\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n但它应该给出它正在自然滚动的提要,并且如果用户在运动状态中间停止滚动,所以我为此添加了motion:onTouchUp="stop"。
这是我的布局文件 -
\n\n<?xml version="1.0" encoding="utf-8"?>\n<androidx.constraintlayout.motion.widget.MotionLayout xmlns:android="http://schemas.android.com/apk/res/android"\n xmlns:app="http://schemas.android.com/apk/res-auto"\n xmlns:tools="http://schemas.android.com/tools"\n xmlns:aapt="http://schemas.android.com/aapt"\n android:id="@+id/hsmerchantListingRoot"\n android:layout_width="match_parent"\n android:layout_height="match_parent"\n app:layoutDescription="@xml/activity_home_services_merchant_listing_scene"\n tools:context="com.nearbuy.nearbuymobile.modules.home_services.HomeServicesMerchantListingActivity">\n\n <androidx.constraintlayout.widget.ConstraintLayout\n android:id="@+id/product_details"\n android:layout_width="match_parent"\n android:layout_height="wrap_content"\n android:paddingBottom="@dimen/dp_15"\n android:visibility="visible"\n app:layout_constraintEnd_toEndOf="parent"\n app:layout_constraintStart_toStartOf="parent"\n app:layout_constraintTop_toTopOf="parent"\n tools:visibility="gone">\n\n <com.nearbuy.nearbuymobile.view.infiniteRotationView.InfiniteRotationView\n android:id="@+id/productImageCarousel"\n android:layout_width="match_parent"\n android:layout_height="wrap_content"\n app:layout_constraintEnd_toEndOf="parent"\n app:layout_constraintStart_toStartOf="parent"\n app:layout_constraintTop_toTopOf="parent" />\n\n <WebView\n android:id="@+id/htmlView"\n android:layout_width="match_parent"\n android:layout_height="wrap_content"\n android:visibility="gone"\n …Run Code Online (Sandbox Code Playgroud) 我有一个场景,它有一个开始约束布局和一个结束。问题是,滑动动画很突然。它只是在单个帧中将开始到结束以及结束到开始进行转换,并且不进行动画处理。Onclick 手势确实有动画效果,但我想使用滑动手势
xml 文件夹内的motionscene.xml
<?xml version="1.0" encoding="utf-8"?>
<MotionScene
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetStart="@layout/backdrop_layout_end"
motion:constraintSetEnd="@layout/backdrop_layout_start"
motion:motionInterpolator="easeInOut"
motion:transitionDisable="false"
motion:duration="200">
<OnSwipe
motion:touchAnchorId="@id/toggle"
motion:dragDirection="dragDown"
motion:maxAcceleration=".5"
/>
</Transition>
</MotionScene>
Run Code Online (Sandbox Code Playgroud)
布局文件夹内的layout_start.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:motion="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/backdrop_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:background="@color/amber_800"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/backdrop_front"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1"
android:background="@drawable/upper_rounded_corners"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="100dp">
<ImageView
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/margin_10"
android:id="@+id/toggle"
android:layout_gravity="center"
android:src="@drawable/ic_adjust"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Run Code Online (Sandbox Code Playgroud)
布局文件夹中的layout_end.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:motion="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/backdrop_back"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent" …Run Code Online (Sandbox Code Playgroud) xml android android-studio android-constraintlayout android-motionlayout
我有一些项目包装在 MotionLayout 和 recyclerView 中,其中需要将一项设置为“结束”状态,并将其余项目保留在“开始”状态,没有任何动画或闪烁,只需显示。

当我尝试打电话时
transitionToState(endState)
Run Code Online (Sandbox Code Playgroud)
或者
transitionToEnd()
Run Code Online (Sandbox Code Playgroud)
动画发生了,但我只需要第一次将元素设置为结束状态。当用户单击项目时,所有内容都应该有动画
android android-animation android-recyclerview android-constraintlayout android-motionlayout