Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animation on layout_gravity

In Android, is it possible to apply an animation on layout_gravity ? for example suppose I want to change the layout_gravity of a View(e.g. Button) from right to left

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="match_parent">
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="New Button"
        android:id="@+id/button"
        android:layout_gravity="right|top" />
</FrameLayout>

In the above layout file I want to change layout gravity from right|top to left|top at run-time with animation, is it possible at all? Thanks

like image 466
frogatto Avatar asked Jan 25 '14 11:01

frogatto


People also ask

How do I animate a view in Android?

You can use the view animation system to perform tweened animation on Views. Tween animation calculates the animation with information such as the start point, end point, size, rotation, and other common aspects of an animation.

What is true about Layout_gravity attribute in Linearlayout?

The layout_gravity attribute can be used to position the Button as a whole with the Button text centered in side it. The gravity attribute can be used to position the text inside the Button. See the screenshot below showing the use of the layout_gravity attribute and the gravity attribute for the Button widget.


2 Answers

You can use a LayoutTransition on the parent ViewGroup to make it animate changes to child views, such as layout changes. In the example below, I animate a floating action button from bottom right of the screen to top right, whilst also rotating it (so the '+' icon becomes an 'x' icon).

Set animateLayoutChanges to true on your containing layout:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/pnlFabContainer"
    android:animateLayoutChanges="true"
    android:clipChildren="false">

    <ExpandableListView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:id="@+id/lstWhatever"
        android:divider="@color/DividerDarkGrey"
        android:dividerHeight="1dp"
        android:choiceMode="singleChoice"
        android:groupIndicator="@null"
        android:padding="20dp"/>

    <com.melnykov.fab.FloatingActionButton
        android:id="@+id/fabMultiSelect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="24dp"
        android:src="@drawable/button_plus"
        android:scaleType="center"
        fab:fab_type="normal"
        fab:fab_colorNormal="@color/FloatingActionButton"
        fab:fab_colorPressed="@color/FloatingActionButtonPressed"
        fab:fab_colorRipple="@color/FloatingActionButtonRipple" />

</FrameLayout>

Enable the 'changing' transition on your container:

FrameLayout pnlFabContainer = (FrameLayout)view.findViewById(R.id.pnlFabContainer);
LayoutTransition transition = pnlFabContainer.getLayoutTransition();
transition.enableTransitionType(LayoutTransition.CHANGING);

animateFabButton(fab);

Then change your layout gravity programmatically - I'm also doing a rotate animation at the same time:

protected void animateFabButton(FloatingActionButton fab) {
    if (fab.isSelected()) {
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)fab.getLayoutParams();
        layoutParams.gravity = Gravity.TOP | Gravity.END;
        layoutParams.topMargin = -(fab.getMeasuredHeight() / 2);
        fab.setLayoutParams(layoutParams);

        Animation rotate = new RotateAnimation(0, 45, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotate.setFillBefore(true);
        rotate.setFillAfter(true);
        rotate.setFillEnabled(true);
        rotate.setDuration(750);
        rotate.setRepeatCount(0);
        rotate.setInterpolator(new LinearInterpolator());
        fab.startAnimation(rotate);
    }
    else {
        FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams)fab.getLayoutParams();
        layoutParams.gravity = Gravity.BOTTOM | Gravity.END;
        layoutParams.topMargin = layoutParams.bottomMargin;
        fab.setLayoutParams(layoutParams);

        Animation rotate = new RotateAnimation(45, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        rotate.setFillBefore(true);
        rotate.setFillAfter(true);
        rotate.setFillEnabled(true);
        rotate.setDuration(750);
        rotate.setRepeatCount(0);
        rotate.setInterpolator(new LinearInterpolator());
        fab.startAnimation(rotate);
    }
}
like image 186
Breeno Avatar answered Oct 20 '22 08:10

Breeno


Its not possible with the layout_gravity attribute. You can achieve the effect with the help of translate animation which runs forever.

Animation animation = new TranslateAnimation(0, 500,0, 0);
animation.setDuration(1000);
animation.setFillAfter(true);
myImage.startAnimation(animation);

This code will only change the position to +500 on x axis

like image 1
Hardik4560 Avatar answered Oct 20 '22 06:10

Hardik4560