motion layout programmatically - android

This is my first question on this platform, I am making a part of an app where I need to dynamically move text views with motion layout, but when I add my showBubble () method this when executing the app does not show the text view, there is something I miss?
I think there is some error in the XML when detecting the id of the BubbleUi, but at the end of the day, it may be easier than it seems, you know :(
note: I am translating this text, sorry if there is any mistake in the writing
XML:
<?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/end"
motion:constraintSetStart="#+id/start"
motion:duration="3500"
>
<OnClick
motion:targetId="#+id/Bubble"
motion:clickAction="toggle"
/>
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#id/Bubble"
android:layout_width="70dp"
android:layout_height="70dp"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
>
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#color/colorGreenLight"
/>
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/Bubble"
android:layout_width="100dp"
android:layout_height="100dp"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
>
<CustomAttribute
motion:attributeName="backgroundColor"
motion:customColorValue="#color/colorGreenLight"
/>
</Constraint>
</ConstraintSet>
</MotionScene>
java:
private void ShowBubble(String tempWord) {
//Create Motion layout.
MotionLayout motionBubble = new MotionLayout(ActivityGame.this);
motionBubble.setId(View.generateViewId());
motionBubble.setBackgroundColor(getResources().getColor(R.color.colorPrimary));
LinearLayout.LayoutParams linearParams= new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT);
linearParams.setMargins(5,0,5,0);
motionBubble.setLayoutParams(linearParams);
//Create the Bubble.
TextView BubbleUi = new TextView(ActivityGame.this);
BubbleUi.setId(R.id.Bubble);
BubbleUi.setText(tempWord);
BubbleUi.setTextSize(24);
BubbleUi.setTextColor(getResources().getColor(R.color.colorDefaultWhite));
BubbleUi.setBackgroundColor(getResources().getColor(R.color.colorGreenLight));
BubbleUi.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
BubbleUi.setGravity(Gravity.CENTER);
motionBubble.addView(BubbleUi,0);
ConstraintSet constraintSetBubble = new ConstraintSet();
constraintSetBubble.clone(motionBubble);
constraintSetBubble.connect(BubbleUi.getId(),ConstraintSet.TOP,ConstraintSet.PARENT_ID,ConstraintSet.TOP);
constraintSetBubble.connect(BubbleUi.getId(),ConstraintSet.START,ConstraintSet.PARENT_ID,ConstraintSet.START);
constraintSetBubble.connect(BubbleUi.getId(),ConstraintSet.END,ConstraintSet.PARENT_ID,ConstraintSet.END);
constraintSetBubble.applyTo(motionBubble);
//set transition.
motionBubble.loadLayoutDescription(R.xml.scene_bubbles);
linearLayoutBubbles.addView(motionBubble,indiceBubble);
CurrentMotionBubbleCycle [indiceBubble] = motionBubble;
motionBubble.transitionToStart();
motionBubble.transitionToEnd();
}

Related

How to animate layout_constraintEnd attribute with intermediate states using MotionLayout?

In my animation one of the views must grow from fixed width to app:layout_constraintEnd_toEndOf="parent" (which is the value from the destination ConstraintSet) by 70% of animation time.
I tried to achive it with the following KeyAttribute:
<KeyAttribute
motion:motionTarget="#id/my_view"
motion:framePosition="70"
>
<CustomAttribute
motion:attributeName="layout_constraintEnd_toEndOf"
motion:customReference="#id/root"/>
</KeyAttribute>
But it has no effect
I would be grateful for working solution of this problem.
If in any case you are interested in Motion Layout for Constraint layout, then you can refer to this provided link for your animation Motion Layout with Stevdza.
MotionLayout animates Views between two ConstraintSets.
It cannot animate Constraints.
You define KeyPosition
With its Size reaching 100% of the size by frame 70.
Constraints control the start and end.
KeyPosition controls the evolution position & size from "start" to "end"
Attributes typically control the viewTransform
For a brief introduction see the KeyPosition video in the MotionTags Series
This is roughly what it should look like:
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#id/start"
motion:duration="1000">
<KeyFrameSet>
<KeyPosition
motion:framePosition="70"
motion:motionTarget="#+id/view"
motion:sizePercent="1"/>
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/end"
motion:deriveConstraintsFrom="#id/start" >
<Constraint
android:id="#+id/view"
android:layout_width="40dp"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"
/>
</ConstraintSet>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintStart_toStartOf="parent"
/>
</ConstraintSet>

Changing height and width of view in keyframes

I need animation which expands a view from height and width of wrap_contents to match constraints, in my case it is to expand as much as parent allows in width but in 50% animation I want that view to first move to center without modifying its height or width.
In first constraint set i have:
<ConstraintSet android:id="#+id/base">
<Constraint android:id="#+id/backgroundView">
<Layout
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_marginEnd="12dp"
android:layout_marginBottom="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<CustomAttribute
app:attributeName="radius"
app:customDimension="30dp" />
</Constraint>
</ConstraintSet>
And the final one is:
<ConstraintSet
android:id="#+id/final"
app:deriveConstraintsFrom="#id/base">
<Constraint android:id="#+id/backgroundView">
<Layout
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="0dp"
android:layout_marginBottom="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<CustomAttribute
app:attributeName="radius"
app:customDimension="12dp" />
</Constraint>
</ConstraintSet>
My transition is:
<Transition
app:constraintSetEnd="#id/final"
app:constraintSetStart="#id/base"
app:duration="300"
app:motionInterpolator="easeInOut">
<KeyFrameSet>
<KeyPosition
app:framePosition="50"
app:keyPositionType="parentRelative"
app:motionTarget="#id/backgroundView"
app:pathMotionArc="startHorizontal"
app:percentX="0.5"
app:percentY="0.5" />
<KeyAttribute
app:framePosition="50"
app:motionTarget="#id/backgroundView">
<CustomAttribute
app:attributeName="radius"
app:customDimension="30dp" />
</KeyAttribute>
</KeyFrameSet>
</Transition>
With this transition I managed to move the view to center but at the same time view is expanding to match new constraints. How can I keep the view to have width and height of 60dp until frame position goes past 50?
Just add this key position to your keyframe set:
<KeyPosition
app:keyPositionType="deltaRelative"
app:framePosition="50"
app:motionTarget="#id/backgroundView"
app:sizePercent="0" />
By combining keyPositionType="deltaRelative" and sizePercent="0" you define that start size should remain unchanged until this key frame.

How to replicate YouTubes "pull down to exit fullscreen" gesture?

I'm trying to create an app using exoplayer, and I'd like to implement a "pull down to exit fullscreen" gesture just like the youtube app has. The gesture itself seems to be doable using a gesture detector, but i don't have a ideo how to create the "pulling down and shrinking the whole video" effect.
Like this
How can i implement this?
To implement this I think you can use MotionLayout. You can take a look to the documentation here: https://developer.android.com/training/constraint-layout/motionlayout/examples
With MotionLayout you can have a view that can be your fullscreen video or whatever and you can animate it based on an action like the user draggin. It defines the animation in a MotionScene like this:
<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="linear">
<OnSwipe
motion:dragDirection="dragRight"
motion:touchAnchorId="#id/button"
motion:touchAnchorSide="right" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#id/button"
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">
<CustomAttribute
motion:attributeName="BackgroundColor"
motion:customColorValue="#D81B60" />
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#id/button"
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">
<CustomAttribute
motion:attributeName="BackgroundColor"
motion:customColorValue="#9999FF" />
</Constraint>
</ConstraintSet>
</MotionScene>
You can see that you can define the action as a new node like the OnSwipe, there you specify the direction and the touch properties. I think the documentation can help expand on all the posibilities, please take a look.

UNKNOWN customName ImageAlpha error in logs for MotionLayout

I've just started working on MotionLayout and it's really easy so far and I'm getting the required output too. But log is filled with errors E/MotionPaths: UNKNOWN customName ImageAlpha
Official documentation also writes
motion:attributeName is required and must match an object with getter and setter methods. The getter and setter much match a specific pattern.
So, what am I doing wrong here?
motion_layout.xml
<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">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="#id/store_viewpager"
motion:touchAnchorSide="top" />
<KeyFrameSet>
<KeyAttribute
motion:framePosition="60"
motion:motionTarget="#id/tab_image_view">
<CustomAttribute
motion:attributeName="imageAlpha"
motion:customIntegerValue="255" />
</KeyAttribute>
<KeyAttribute
motion:framePosition="90"
motion:motionTarget="#id/tab_image_view">
<CustomAttribute
motion:attributeName="imageAlpha"
motion:customIntegerValue="0" />
</KeyAttribute>
</KeyFrameSet>
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/tab_image_view"
android:layout_height="256dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/tab_image_view"
android:layout_height="96dp"
motion:layout_constraintEnd_toEndOf="parent"
motion:layout_constraintStart_toStartOf="parent"
motion:layout_constraintTop_toTopOf="parent">
</Constraint>
</ConstraintSet>
</MotionScene>
It is saying it cant find "imageAlpha". Your customAttributes
implies you have a method setImageAlpha(int) on "#+id/tab_image_view".
Assuming it is an ImageView that it would work but only back to api 16.
Alpha is a little more generic operating from 0.0 to 1.0 and is on View.
You do not need a custom attribute for it. android:alpha="0"
To help further what is the View? (ImageView?)
What device level?

Is it possible to animate groups visibility with MotionLayout?

I'm trying to make an animation with MotionLayout, and I need to hide some elements.
I tested visibility attribute in an individual element and it works, but to make the XML shorter I would like to be able to specify just a group (from the ConstraintLayout helpers) containing all this elements
Something like this
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetStart="#id/start"
app:constraintSetEnd="#id/end"
app:duration="300">
<OnSwipe
app:touchAnchorId="#id/details_group"
app:touchAnchorSide="bottom"
app:dragDirection="dragDown"
/>
</Transition>
<ConstraintSet
android:id="#+id/start">
<Constraint
android:id="#+id/details_group"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="gone"
app:constraint_referenced_ids="detail_value_topl,detail_icon_topl,detail_value_topr" />
</ConstraintSet>
<ConstraintSet
android:id="#+id/end">
<Constraint
android:id="#+id/details_group"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="visible"
app:constraint_referenced_ids="detail_value_topl,detail_icon_topl,detail_value_topr" />
</ConstraintSet>
</MotionScene>
But it doesn't work, any idea how to make it work ?
Also, I would prefer not to use alpha, since all constraints are set so that when they are gone the container resizes
Rather than declaring the visibility on the Constraint, you should declare the visibility as a custom attribute. So for your first constraint try this:
<Constraint
android:id="#+id/details_group"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="detail_value_topl,detail_icon_topl,detail_value_topr">
<CustomAttribute
motion:attributeName="visibility"
motion:customIntegerValue="8" />
</Constraint>
and for your second constraint try this
<Constraint
android:id="#+id/details_group"
android:layout_width="0dp"
android:layout_height="0dp"
app:constraint_referenced_ids="detail_value_topl,detail_icon_topl,detail_value_topr">
<CustomAttribute
motion:attributeName="visibility"
motion:customIntegerValue="0" />
</Constraint>
By declaring the visibility as a custom attribute, that should help the motion layout properly interpolate between visibility values. It's a little unintuitive which int value is which visibility but they are defined as follows
Visible = 0
Invisible = 4
Gone = 8

Categories

Resources