Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Android application demonstrating the usage of ViewOverlay and OnPreDrawListener to achieve animations effects.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="horizontal"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<LinearLayout
android:id="@+id/source_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="5"
android:background="#eee"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" >
<TextView
style="@style/column_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Source" />
</LinearLayout>
<LinearLayout
android:id="@+id/destination_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="@dimen/activity_vertical_margin"
android:layout_weight="2"
android:background="#eee"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin" >
<TextView
style="@style/column_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Destination" />
</LinearLayout>
</LinearLayout>
package com.example.overlay;
public class Entry {
private final int imageResId;
private final String title;
public Entry( int imageResId, String title ) {
this.imageResId = imageResId;
this.title = title;
}
public int getImageResId() {
return imageResId;
}
public String getTitle() {
return title;
}
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/entry_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin"
android:layout_marginTop="@dimen/activity_vertical_margin" >
<LinearLayout
android:id="@+id/entry"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/background_light"
android:gravity="center_vertical"
android:orientation="horizontal" >
<ImageView
android:id="@+id/entry_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="4dp" />
<TextView
android:id="@+id/entry_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</FrameLayout>
package com.example.overlay;
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnPreDrawListener;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ItemClickListener implements OnClickListener {
private final Entry entry;
private final ImageView srcView;
private final ViewGroup rootView;
private final ViewGroup destContainer;
private final Activity activity;
public ItemClickListener( Activity activity, Entry entry, ImageView srcView ) {
this.activity = activity;
this.entry = entry;
this.srcView = srcView;
this.rootView = ( ViewGroup )activity.findViewById( R.id.root_layout );
this.destContainer = ( LinearLayout )activity.findViewById( R.id.destination_container );
}
@Override
public void onClick( View v ) {
final FrameLayout destView = createDestView();
final ViewTreeObserver observer = destView.getViewTreeObserver();
observer.addOnPreDrawListener( new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
observer.removeOnPreDrawListener( this );
final LinearLayout entryView = ( LinearLayout )destView.findViewById( R.id.entry );
final ImageView imageView = ( ImageView )destView.findViewById( R.id.entry_image );
imageView.setTranslationX( getAbsX( srcView ) - getAbsX( imageView ) );
imageView.setTranslationY( getAbsY( srcView ) - getAbsY( imageView ) );
rootView.getOverlay().add( imageView );
imageView.animate()
.translationX( 0 )
.translationY( 0 )
.setInterpolator( new DecelerateInterpolator( 2 ) )
.setDuration( 500 );
destContainer.getOverlay().add( entryView );
destView.getLayoutParams().height = entryView.getMeasuredHeight();
entryView.setAlpha( 0 );
entryView.setTranslationY( 100 );
entryView.animate()
.translationY( 0 )
.setDuration( 500 )
.alpha( 1 )
.setStartDelay( 0 )
.setInterpolator( new DecelerateInterpolator( 2 ) )
.withEndAction( new Runnable() {
@Override
public void run() {
destContainer.getOverlay().remove( entryView );
destView.addView( entryView );
rootView.getOverlay().remove( imageView );
entryView.addView( imageView, 0 );
}
} );
return true;
}
} );
}
private float getAbsX( View view ) {
if( view.getParent() == view.getRootView() ) {
return view.getX();
} else {
return view.getX() + getAbsX( ( View )view.getParent() );
}
}
private float getAbsY( View view ) {
if( view.getParent() == view.getRootView() ) {
return view.getY();
} else {
return view.getY() + getAbsY( ( View )view.getParent() );
}
}
private FrameLayout createDestView() {
LayoutInflater layoutInflater = LayoutInflater.from( activity );
FrameLayout destView = ( FrameLayout )layoutInflater.inflate( R.layout.entry,
destContainer,
false );
ImageView imageView = ( ImageView )destView.findViewById( R.id.entry_image );
imageView.setImageResource( entry.getImageResId() );
TextView textView = ( TextView )destView.findViewById( R.id.entry_text );
textView.setText( entry.getTitle() );
destContainer.addView( destView );
return destView;
}
}
package com.example.overlay;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
private final ArrayList<Entry> entries;
public MainActivity() {
entries = new ArrayList<Entry>();
entries.add( new Entry( R.drawable.collections_go_to_today, "Calendar" ) );
entries.add( new Entry( R.drawable.content_read, "Envelope" ) );
entries.add( new Entry( R.drawable.location_web_site, "Location" ) );
entries.add( new Entry( R.drawable.social_group, "Social Group" ) );
}
@Override
protected void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
createSourceItems();
}
private void createSourceItems() {
LinearLayout sourceContainer = ( LinearLayout )findViewById( R.id.source_container );
for( Entry entry : entries ) {
ImageView srcView = new ImageView( this );
srcView.setImageResource( entry.getImageResId() );
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT );
params.topMargin = getResources().getDimensionPixelSize( R.dimen.activity_vertical_margin );
sourceContainer.addView( srcView, params );
ItemClickListener listener = new ItemClickListener( this, entry, srcView );
srcView.setOnClickListener( listener );
}
}
@Override
public boolean onCreateOptionsMenu( Menu menu ) {
MenuInflater inflater = getMenuInflater();
inflater.inflate( R.menu.main, menu );
return true;
}
@Override
public boolean onMenuItemSelected( int featureId, MenuItem item ) {
boolean result = super.onMenuItemSelected( featureId, item );
if( item.getItemId() == R.id.action_clear ) {
LinearLayout destinationContainer = ( LinearLayout )findViewById( R.id.destination_container );
int childCount = destinationContainer.getChildCount();
for( int i = 1; i < childCount; i++ ) {
destinationContainer.removeViewAt( 1 );
}
}
return result;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment