Monday, April 13, 2015

ObjectAnimator play sequentially in Android

Android ObjectAnimator Play Sequentially
activity_main.xml

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="20dp"
    android:paddingRight="20dp"
    android:paddingTop="25dp"
    android:paddingBottom="40dp"
    tools:context=".MainActivity"
    android:id="@+id/rl"
    android:background="@drawable/relative_layout_border"
    >
    <ImageView
        android:id="@+id/img"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:src="@drawable/square"
        android:layout_centerInParent="true"
        />
    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:background="@drawable/textview_bg"
        />
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Move Square"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:onClick="onButtonClicked"
        />
</RelativeLayout>
res/drawable/textview_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <solid android:color="#99ffffff"/>
            <stroke android:color="#00ff00" android:width="1dp"/>
        </shape>
    </item>
</selector>
res/drawable/relative_layout_border.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <stroke android:color="#ff0000" android:width="1dp"/>
        </shape>
    </item>
</selector>
res/drawable/square.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape android:shape="rectangle">
            <size android:height="75dp" android:width="75dp"/>
            <solid android:color="#C0C0C0"/>
            <stroke android:color="#000000" android:width="1dp"/>
        </shape>
    </item>
</selector>
MainActivity.java (Partial code)

public void onButtonClicked(View v){
 final RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);
 final Button btn = (Button) findViewById(R.id.btn);
 final ImageView img = (ImageView) findViewById(R.id.img);
 final TextView tv = (TextView) findViewById(R.id.tv);

 //Get image animation starting position X and Y
 final float imgTX = img.getTranslationX();
 final float imgTY = img.getTranslationY();

 final AnimatorSet animatorSet = new AnimatorSet();
 animatorSet.playSequentially(
   //Move to container Top Left
   ObjectAnimator.ofPropertyValuesHolder(
     img,
     PropertyValuesHolder.ofFloat("translationX", (float) getMovableEdge(rl, img).get("Left")),
     PropertyValuesHolder.ofFloat("translationY", (float) getMovableEdge(rl, img).get("Top")))
     .setDuration(1000),
   //Move to container Top Right
   ObjectAnimator.ofPropertyValuesHolder(
     img,
     PropertyValuesHolder.ofFloat("translationX", (float) getMovableEdge(rl, img).get("Right")),
     PropertyValuesHolder.ofFloat("translationY", (float) getMovableEdge(rl, img).get("Top")))
     .setDuration(1000),
   //Move to container Bottom Right
   ObjectAnimator.ofPropertyValuesHolder(
     img,
     PropertyValuesHolder.ofFloat("translationX", (float) getMovableEdge(rl, img).get("Right")),
     PropertyValuesHolder.ofFloat("translationY", (float) getMovableEdge(rl, img).get("Bottom")))
     .setDuration(1000),
   //Move to container Bottom Left
   ObjectAnimator.ofPropertyValuesHolder(
     img,
     PropertyValuesHolder.ofFloat("translationX", (float) getMovableEdge(rl, img).get("Left")),
     PropertyValuesHolder.ofFloat("translationY", (float) getMovableEdge(rl, img).get("Bottom")))
     .setDuration(1000),
   //Move to container Top Left
   ObjectAnimator.ofPropertyValuesHolder(
     img,
     PropertyValuesHolder.ofFloat("translationX", (float) getMovableEdge(rl, img).get("Left")),
     PropertyValuesHolder.ofFloat("translationY", (float) getMovableEdge(rl, img).get("Top")))
     .setDuration(1000),
   //Move image to animation starting position
   ObjectAnimator.ofPropertyValuesHolder(
     img,
     PropertyValuesHolder.ofFloat("translationX", imgTX),
     PropertyValuesHolder.ofFloat("translationY", imgTY))
     .setDuration(1000)
 );
 animatorSet.start();
 btn.setEnabled(false);

 animatorSet.addListener(new AnimatorListenerAdapter() {
  @Override
  public void onAnimationEnd(Animator animation)
  {
   animation.start();
  }
 });
}

public Map getMovableEdge(ViewGroup container, View view){
 //Get ultimate left edge (X) of container to move
 float movableLeft = -(view.getX()-container.getPaddingLeft()); //with negative (minus) sign
 //Get ultimate right edge (X) of container to move
 float movableRight = container.getWidth()-container.getPaddingRight()-view.getX()-view.getWidth();

 //Get ultimate top edge (Y) of container to move
 //with negative (minus) sign
 float movableTop = -(container.getHeight()-container.getPaddingTop()-view.getHeight()-view.getY());
 //Get ultimate bottom edge (Y) of container to move
 float movableBottom = view.getY()-container.getPaddingBottom();

 //Initialize a new Dictionary object
 Map<String, Float> map = new HashMap<String, Float>();
 map.put("Left", movableLeft);
 map.put("Right", movableRight);
 map.put("Top", movableTop);
 map.put("Bottom", movableBottom);

 //Return the Dictionary object with values
 return map;
}
Additional imported classes

import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.HashMap;
import java.util.Map;
import android.animation.AnimatorSet;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.AnimatorListenerAdapter;
More android examples