How to Animate a Slide in Notification View That Pushes the Content View Down

How to animate a slide in notification view that pushes the content view down

This worked for me

No notificationAnimating notificationNotification visibleAnimating notificationNo notification

First you must import this library: http://nineoldandroids.com/

The import is done by importing existing android project into your workspace, afterwards right click your Poject -> Properties -> Android. Here you will see a library section, click the Add button and add the nineoldandroids library.

First off, here is the layout xml used for this to work:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<FrameLayout
android:id="@+id/frameLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >

<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent"
android:divider="@android:color/transparent"
android:fastScrollEnabled="false"
android:listSelector="@android:color/transparent"
android:scrollbars="vertical"
android:smoothScrollbar="true" />

<View
android:id="@+id/greenView"
android:layout_width="match_parent"
android:layout_height="150dp"
android:background="#ff00ff00"
android:alpha="0"/>
</FrameLayout>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >

<Button
android:id="@+id/animate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="clickHandler"
android:text="animate" />

<Button
android:id="@+id/close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="clickHandler"
android:text="close" />
</LinearLayout>

Notice: Both the ListView and the green View could be layouts of any types with any kind of content.

And next a proof of concept Activity.

public class TestActivity extends Activity {

private View greenView;
private ListView listView;
private int greenHeight;

private boolean isShowingBox;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);

// The animated view
greenView = (View)findViewById(R.id.greenView);
listView = (ListView)findViewById(R.id.listView1);

// Instanciating an array list (you don't need to do this, you already have yours)
ArrayList<String> your_array_list = new ArrayList<String>();
your_array_list.add("1");
your_array_list.add("2");
your_array_list.add("3");
your_array_list.add("4");
your_array_list.add("5");
your_array_list.add("6");
your_array_list.add("7");
your_array_list.add("8");
your_array_list.add("9");
your_array_list.add("10");
your_array_list.add("11");
your_array_list.add("12");
your_array_list.add("13");
your_array_list.add("14");
your_array_list.add("15");
// This is the array adapter, it takes the context of the activity as a first // parameter, the type of list view as a second parameter and your array as a third parameter
ArrayAdapter<String> arrayAdapter =
new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, your_array_list);
listView.setAdapter(arrayAdapter);

final LinearLayout layout = (LinearLayout)findViewById(R.id.parentLayout);

final ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {

if (Build.VERSION.SDK_INT < 16) {
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}

greenHeight = greenView.getHeight();

}
});
}

public void clickHandler(View v) {
if (isShowingBox) {
isShowingBox = false;
slideOut(1500, 0);
} else {
isShowingBox = true;
slideIn(1500, 0);
}
}

private void slideIn(int duration, int delay) {
AnimatorSet set = new AnimatorSet();
set.playTogether(
// animate from off-screen in to screen
ObjectAnimator.ofFloat(greenView, "translationY", -greenHeight, 0),
ObjectAnimator.ofFloat(listView, "translationY", 0, greenHeight),
ObjectAnimator.ofFloat(greenView, "alpha", 0, 0.25f, 1)
// add other animations if you wish
);
set.setStartDelay(delay);
set.setDuration(duration).start();
}

private void slideOut(int duration, int delay) {
AnimatorSet set = new AnimatorSet();
set.playTogether(
// animate from on-screen and out
ObjectAnimator.ofFloat(greenView, "translationY", 0, -greenHeight),
ObjectAnimator.ofFloat(listView, "translationY", greenHeight, 0),
ObjectAnimator.ofFloat(greenView, "alpha", 1, 1, 1)
// add other animations if you wish
);
set.setStartDelay(delay);
set.setDuration(duration).start();
}

}

Important note: Remember to import the AnimatorSet and ObjectAnimator from nineoldandroids in your class and not the Android SDK ones!!!

Show and hide a View with a slide up/down animation

With the new animation API that was introduced in Android 3.0 (Honeycomb) it is very simple to create such animations.

Sliding a View down by a distance:

view.animate().translationY(distance);

You can later slide the View back to its original position like this:

view.animate().translationY(0);

You can also easily combine multiple animations. The following animation will slide a View down by its height and fade it in at the same time:

// Prepare the View for the animation
view.setVisibility(View.VISIBLE);
view.setAlpha(0.0f);

// Start the animation
view.animate()
.translationY(view.getHeight())
.alpha(1.0f)
.setListener(null);

You can then fade the View back out and slide it back to its original position. We also set an AnimatorListener so we can set the visibility of the View back to GONE once the animation is finished:

view.animate()
.translationY(0)
.alpha(0.0f)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
});

Animate view sliding out of another view, pushing views below out of the way

I believe the simplest approach is to extend Animation class and override applyTransformation() to change the view's height as follows:

import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;

public class MyCustomAnimation extends Animation {

public final static int COLLAPSE = 1;
public final static int EXPAND = 0;

private View mView;
private int mEndHeight;
private int mType;
private LinearLayout.LayoutParams mLayoutParams;

public MyCustomAnimation(View view, int duration, int type) {

setDuration(duration);
mView = view;
mEndHeight = mView.getHeight();
mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams());
mType = type;
if(mType == EXPAND) {
mLayoutParams.height = 0;
} else {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
}
view.setVisibility(View.VISIBLE);
}

public int getHeight(){
return mView.getHeight();
}

public void setHeight(int height){
mEndHeight = height;
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {

super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
if(mType == EXPAND) {
mLayoutParams.height = (int)(mEndHeight * interpolatedTime);
} else {
mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime));
}
mView.requestLayout();
} else {
if(mType == EXPAND) {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
mView.requestLayout();
}else{
mView.setVisibility(View.GONE);
}
}
}
}

To use it, set your onclick() as follows:

int height;

@Override
public void onClick(View v) {
if(view2.getVisibility() == View.VISIBLE){
MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.COLLAPSE);
height = a.getHeight();
view2.startAnimation(a);
}else{
MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.EXPAND);
a.setHeight(height);
view2.startAnimation(a);
}
}

Regards.

Animate view sliding out of another view, pushing views below out of the way

I believe the simplest approach is to extend Animation class and override applyTransformation() to change the view's height as follows:

import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Transformation;
import android.widget.LinearLayout;

public class MyCustomAnimation extends Animation {

public final static int COLLAPSE = 1;
public final static int EXPAND = 0;

private View mView;
private int mEndHeight;
private int mType;
private LinearLayout.LayoutParams mLayoutParams;

public MyCustomAnimation(View view, int duration, int type) {

setDuration(duration);
mView = view;
mEndHeight = mView.getHeight();
mLayoutParams = ((LinearLayout.LayoutParams) view.getLayoutParams());
mType = type;
if(mType == EXPAND) {
mLayoutParams.height = 0;
} else {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
}
view.setVisibility(View.VISIBLE);
}

public int getHeight(){
return mView.getHeight();
}

public void setHeight(int height){
mEndHeight = height;
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {

super.applyTransformation(interpolatedTime, t);
if (interpolatedTime < 1.0f) {
if(mType == EXPAND) {
mLayoutParams.height = (int)(mEndHeight * interpolatedTime);
} else {
mLayoutParams.height = (int) (mEndHeight * (1 - interpolatedTime));
}
mView.requestLayout();
} else {
if(mType == EXPAND) {
mLayoutParams.height = LayoutParams.WRAP_CONTENT;
mView.requestLayout();
}else{
mView.setVisibility(View.GONE);
}
}
}
}

To use it, set your onclick() as follows:

int height;

@Override
public void onClick(View v) {
if(view2.getVisibility() == View.VISIBLE){
MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.COLLAPSE);
height = a.getHeight();
view2.startAnimation(a);
}else{
MyCustomAnimation a = new MyCustomAnimation(view2, 1000, MyCustomAnimation.EXPAND);
a.setHeight(height);
view2.startAnimation(a);
}
}

Regards.

Animation in Notification bar Custom View

The best way I have found to show a custom animation in a notification is to use an AnimationDrawable as a resource with an ID. Then simply specify the drawable resource ID when you post your notification. No further code is needed to update each frame of the animation. The animation drawable handles that for you.

Here is a link to documentation: http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html

So for example you would need to:

  1. Add an xml file (such as "wheelAnim.xml") to your res/drawable/ folder with the following contents:

    <!-- Animation frames are wheel0.png -- wheel5.png files inside the
    res/drawable/ folder -->
    <animation-list android:id="selected" android:oneshot="false">
    <item android:drawable="@drawable/wheel0" android:duration="50" />
    <item android:drawable="@drawable/wheel1" android:duration="50" />
    <item android:drawable="@drawable/wheel2" android:duration="50" />
    <item android:drawable="@drawable/wheel3" android:duration="50" />
    <item android:drawable="@drawable/wheel4" android:duration="50" />
    <item android:drawable="@drawable/wheel5" android:duration="50" />
    </animation-list>
  2. Add each drawable reference in the xml file you just created for the animation-list (be it PNG or other image format) in the res/drawable/ folder as well.

  3. Use the resource ID of the animation-list (which in this example is "R.drawable.wheelAnim") in your code. For example:

    Notification notification = new Notification(R.drawable.wheelAnim, null,
    System.currentTimeMillis());

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
    new Intent(), 0);

    notification.flags |= Notification.FLAG_AUTO_CANCEL;

    notification.setLatestEventInfo(this, getText(R.string.someTitle),
    getText(R.string.someText), pendingIntent);

    ((NotificationManager) getSystemService(NOTIFICATION_SERVICE)).notify(
    uid, notification);


Related Topics



Leave a reply



Submit