问题
I have an ImageFilterView view that I am animating using a MotionLayout. It starts as a small square view with roundPercent set to 1.0 (so that it is also a circle) that hides behind a circle and then animates to a full screen square. It works great the very first time it animates but every other time just stays as a rectangle.
You can see a video of the issue here: VIDEO
I'm not sure if it's a bug on the ImageFilterView or MotionLayout or if I'm calling something incorrectly. It's worth mentioning that instead of using an onClick in the Transition I am programatically calling it in the Activity like so
imageBorder.setOnClickListener {
if (motionContainer.progress > 0.75)
motionContainer.transitionToStart()
else
motionContainer.transitionToEnd()
}
My motionScene code looks like the following
<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"
motion:motionInterpolator="easeInOut" />
<ConstraintSet android:id="@+id/start">
<Constraint android:id="@id/translucentOverlay">
<Layout
android:layout_width="5dp"
android:layout_height="5dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBorder"
motion:layout_constraintEnd_toEndOf="@id/imageBorder"
motion:layout_constraintStart_toStartOf="@id/imageBorder"
motion:layout_constraintTop_toTopOf="@id/imageBorder" />
<CustomAttribute
motion:attributeName="roundPercent"
motion:customFloatValue="1.0" />
<Motion motion:motionStagger="2" />
</Constraint>
<Constraint android:id="@id/imageBorder">
<Layout
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="0" />
<Motion motion:motionStagger="2" />
</Constraint>
<Constraint android:id="@id/imageBackground">
<Layout
android:layout_width="32dp"
android:layout_height="32dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBorder"
motion:layout_constraintEnd_toEndOf="@id/imageBorder"
motion:layout_constraintStart_toStartOf="@id/imageBorder"
motion:layout_constraintTop_toTopOf="@id/imageBorder" />
<Motion motion:motionStagger="2" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="@+id/end">
<Constraint android:id="@id/translucentOverlay">
<Layout
android:layout_width="match_parent"
android:layout_height="match_parent" />
<CustomAttribute
motion:attributeName="roundPercent"
motion:customFloatValue="0.0" />
<Motion motion:motionStagger="2" />
</Constraint>
<Constraint android:id="@id/imageBorder">
<Layout
android:layout_width="88dp"
android:layout_height="88dp"
motion:layout_constraintBottom_toBottomOf="@id/imageBackground"
motion:layout_constraintEnd_toEndOf="@id/imageBackground"
motion:layout_constraintStart_toStartOf="@id/imageBackground"
motion:layout_constraintTop_toTopOf="@id/imageBackground" />
<CustomAttribute
motion:attributeName="crossfade"
motion:customFloatValue="1" />
<Motion motion:motionStagger="2" />
</Constraint>
<Constraint android:id="@id/imageBackground">
<Layout
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_marginTop="64dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent" />
<Motion motion:motionStagger="2" />
</Constraint>
</ConstraintSet>
and my MotionLayout looks like this:
<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/motionContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
app:layoutDescription="@xml/motion_scene">
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/translucentOverlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/translucent_background_square"/>
<androidx.constraintlayout.utils.widget.ImageFilterView
android:id="@+id/imageBorder"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_margin="8dp"
android:padding="4dp"
android:src="@drawable/circle_start"
app:altSrc="@drawable/circle_end" />
<ImageView
android:id="@+id/imageBackground"
android:layout_width="32dp"
android:layout_height="32dp"
android:importantForAccessibility="no"
android:tint="@color/primaryDarkColor"
app:srcCompat="@drawable/circle_opaque" />
</androidx.constraintlayout.motion.widget.MotionLayout>
It's very annoying that it stops working after the first time. I have been trying to solve this circle to square problem for a very long time now and I thought I had finally found the solution but it appears not.
回答1:
After more fiddling around, this appears to be a bug in ImageFilterView where if you set roundPercent to 0.0, the view will remain rectangle for the rest of the time. I imagine that it is an issue with dividing by 0 or some bug like that. I have reported the issue to Google Developers so hopefully that will get fixed soon.
In the meantime, you can workaround the issue by setting percentRound to 0.000001 to get around the divide by zero bug.
来源:https://stackoverflow.com/questions/59583838/motionlayout-roundpercent-only-works-one-time