Gmail like listview item remove - android

I'm trying to achieve something the Gmail app (ICS) offers on deleting message. I wan't all rows below deleted cell to move up and cover deleted cell.
Here is working animation:
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false" >
<translate android:fromYDelta="0%" android:toYDelta="-100%"
android:duration="#android:integer/config_mediumAnimTime"/>
<alpha android:fromAlpha="0.0" android:toAlpha="1.0"
android:duration="#android:integer/config_mediumAnimTime" />
</set>
All I came up with so far is this:
public static List<View> getCellsBelow(ListView listView, int position) {
List<View> cells = new ArrayList<View>();
for (int i = position + 1; i <= listView.getLastVisiblePosition(); i++) {
cells.add(listView.getChildAt(i));
}
return cells;
}
I gather visible cells bellow the selected cell and then animate them in foreach. I fear this is performance disaster. I also have trouble notify adapter that it should reload it's content. normally I'd call notifyDataSetChanged on onAnimationEnd but now there are couple of animations playing one after another.
Any suggestions pals? Maybe there is something that allows to animate couple of views stimulatenously?

Update:: I recommend checking out this solution by Chet Haase who works at the Android team. Especially if you are not developing for Android 2.3 and lower.
This should be exactly what you want.
list.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent,
final View view, final int position, long id) {
removeRow(view, position);
return true;
}
});
private void removeRow(final View row, final int position) {
final int initialHeight = row.getHeight();
Animation animation = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
super.applyTransformation(interpolatedTime, t);
int newHeight = (int) (initialHeight * (1 - interpolatedTime));
if (newHeight > 0) {
row.getLayoutParams().height = newHeight;
row.requestLayout();
}
}
};
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
row.getLayoutParams().height = initialHeight;
row.requestLayout();
items.remove(position);
((BaseAdapter) list.getAdapter()).notifyDataSetChanged();
}
});
animation.setDuration(300);
row.startAnimation(animation);
}

The original author of this published the code as a Gist here: https://gist.github.com/2980593
and here is the original Google+ post from Roman Nurik: https://plus.google.com/113735310430199015092/posts/Fgo1p5uWZLu

You can try the ListView I made for this. It's on Github.

Related

Slidedown and slideup layout with animation

how can I display a layout in the center with slideUp when I press the button, and press again to hide ... slideDown in ANDROID
help me with that, thnkss
Create two animation xml under res/anim folder
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="1000"
android:fromYDelta="0"
android:toYDelta="100%" />
</set>
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="1000"
android:fromYDelta="100%"
android:toYDelta="0" />
</set>
Load animation Like bellow Code and start animation when you want According to your Requirement
//Load animation
Animation slide_down = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide_down);
Animation slide_up = AnimationUtils.loadAnimation(getApplicationContext(),
R.anim.slide_up);
// Start animation
linear_layout.startAnimation(slide_down);
I use these easy functions, it work like jquery slideUp slideDown, use it in an helper class, just pass your view :
public static void expand(final View v) {
v.measure(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
// Older versions of android (pre API 21) cancel animations for views with a height of 0.
v.getLayoutParams().height = 1;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? WindowManager.LayoutParams.WRAP_CONTENT
: (int)(targetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration((int) (targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
public static void collapse(final View v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
if(interpolatedTime == 1){
v.setVisibility(View.GONE);
}else{
v.getLayoutParams().height = initialHeight - (int)(initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration((int)(initialHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
Above method is working, but here are more realistic slide up and slide down animations from the top of the screen.
Just create these two animations under the anim folder
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fromYDelta="-100%"
android:toYDelta="0" />
</set>
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="200"
android:fromYDelta="0"
android:toYDelta="-100%" />
</set>
Load animation in java class like this
imageView.startAnimation(AnimationUtils.loadAnimation(getContext(),R.anim.slide_up));
imageView.startAnimation(AnimationUtils.loadAnimation(getContext(),R.anim.slide_down));
This doesn't work for me, I want to to like jquery slideUp / slideDown function, I tried this code, but it only move the content wich stay at the same place after animation end, the view should have a 0dp height at start of slideDown and the view height (with wrap_content) after the end of the animation.
From JAVA file: Use this is the method.
public class ViewAnimatorSlideUpDown {
public static void slideDown(final View view) {
if (view != null) {
view.setVisibility(View.VISIBLE);
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = 1;
view.setLayoutParams(layoutParams);
view.measure(View.MeasureSpec.makeMeasureSpec(Resources.getSystem().getDisplayMetrics().widthPixels,
View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED));
final int height = view.getMeasuredHeight();
ValueAnimator valueAnimator = ObjectAnimator.ofInt(1, height);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
if (height > value) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = value;
view.setLayoutParams(layoutParams);
} else {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
view.setLayoutParams(layoutParams);
}
}
});
valueAnimator.start();
}
}
public static void slideUp(final View view) {
if (view != null) {
view.post(new Runnable() {
#Override
public void run() {
final int height = view.getHeight();
ValueAnimator valueAnimator = ObjectAnimator.ofInt(height, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
if (value > 0) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.height = value;
view.setLayoutParams(layoutParams);
} else {
view.setVisibility(View.GONE);
}
}
});
valueAnimator.start();
}
});
}
}
}
======================================================================
And Use it into Java file ex.
if (binding.llTheme.getVisibility() == View.GONE) {
ViewAnimatorSlideUpDown.slideDown(binding.llTheme);
binding.llTheme.setVisibility(View.VISIBLE);
} else {
binding.llTheme.setVisibility(View.GONE);
ViewAnimatorSlideUpDown.slideUp(binding.llTheme);
}
Done. ☻♥ keep it up.
I had a similar requirement in the app I am working on. And, I found a third-party library which does a slide-up, slide-down and slide-right in Android.
Refer to the link for more details: https://github.com/mancj/SlideUp-Android
To set up the library(copied from the ReadMe portion of its Github page on request):
Get SlideUp library
Add the JitPack repository to your build file. Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
maven { url "https://maven.google.com" } // or google() in AS 3.0
}
}
Add the dependency (in the Module gradle)
dependencies {
compile 'com.github.mancj:SlideUp-Android:2.2.1'
compile 'ru.ztrap:RxSlideUp2:2.x.x' //optional, for reactive listeners based on RxJava-2
compile 'ru.ztrap:RxSlideUp:1.x.x' //optional, for reactive listeners based on RxJava
}
To add the SlideUp into your project, follow these three simple steps:
Step 1:
create any type of layout
<LinearLayout
android:id="#+id/slideView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Step 2:
Find that view in your activity/fragment
View slideView = findViewById(R.id.slideView);
Step 3:
Create a SlideUp object and pass in your view
slideUp = new SlideUpBuilder(slideView)
.withStartState(SlideUp.State.HIDDEN)
.withStartGravity(Gravity.BOTTOM)
//.withSlideFromOtherView(anotherView)
//.withGesturesEnabled()
//.withHideSoftInputWhenDisplayed()
//.withInterpolator()
//.withAutoSlideDuration()
//.withLoggingEnabled()
//.withTouchableAreaPx()
//.withTouchableAreaDp()
//.withListeners()
//.withSavedState()
.build();
You may also refer to the sample project on the link. I found it quite useful.

Dynamic Animation - Android

I currently have a button that when clicked an animation begins that shows a LinearLayout above the button. The LinearLayout is directly above it. In the xml file the LinearLayouts visibility is set to GONE. So when the button is clicked the visibility is set to VISIBLE. Then the animation begins. The animation is a slidedown animation. Everything works perfectly. But When the button is clicked the button jumps to the bottom of where the LinearLayout ends. Even though the LinearLayout is still going through the animation. How can I make the button move with the LinearLayout animation? I want everything to be a smooth transition. But the button jumps and it doesn't look very smooth.
LInearLayout Animation
<?xml version="1.0" encoding="utf-8"?>
<!-- slide down -->
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<scale
android:duration="500"
android:fromXScale="1.0"
android:fromYScale="0.0"
android:interpolator="#android:anim/linear_interpolator"
android:toXScale="1.0"
android:toYScale="1.0" />
</set>
I just ran into a very similar situation today.
I used a custom animation that re sizes the view.
The required height is measured and saved. Initially the height is set to 0 and it grows as the animation goes on. Finally it reaches the measured height and then it is set to wrap content as it was originally.
public static void expand(final View v) {
v.measure(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
final int targetHeight = v.getMeasuredHeight();
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation()
{
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1
? LayoutParams.WRAP_CONTENT
: (int)(targetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
// 1dp/ms
a.setDuration((int)(targetHeight / v.getContext().getResources().getDisplayMetrics().density));
v.startAnimation(a);
}
v should be the LinearLayout you would like to animate.
You can choose a fixed time duration if you preffer.
source: https://stackoverflow.com/a/13381228/1646326
Use custom animation, it's very easy you can change whatever you want in applytransformation,
interpolatedTime - this is current position like in % from start to end animation (and has float value from 0 to 1, so here using this interpolatedTime you can iterate anything you can imagine) ;)
static class HeightAnimation extends Animation{
private View view;
private int mViewHeightFrom;
private int mViewHeightTo;
public HeightAnimation(View view, int heightFrom, int heightTo){
this.view = view;
this.mViewHeightFrom = heightFrom;
this.mViewHeightTo = heightTo;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int)((mViewHeightTo - mViewHeightFrom)*interpolatedTime+0.5));
view.setLayoutParams(params);
}
#Override
public boolean willChangeBounds() {
return true;
}
#Override
public boolean isFillEnabled() {
return true;
}
}
and the usage:
public static void applyAnimationHeightTransformation(Context context, View view, int viewHeightFrom, int viewHeightTo, int duration, int animationOffsetMilisec){
HeightAnimation anim = new HeightAnimation(view, viewHeightFrom, viewHeightTo);
anim.setStartOffset(animationOffsetMilisec);
anim.setDuration(duration);
//anim.setInterpolator(new OvershootInterpolator()); // here interpolators can be used
if(view != null) {
view.setAnimation(anim);
view.startAnimation(anim);
}
}
for height to make easier using - use values in dp via transform to pixels:
public static int dpToPx(int dp) {
return (int)(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, YourApplication.getMainContext().getResources().getDisplayMetrics()));
}

View.getX/Y and View.setX/Y below Android 3.0

I am working on a project that must work on Android 2.2 onwards, and I just realized I was using a 3.0+ method from View.
I have a menu that animates vertically sliding in/out when a button is pressed. When the animation finishes I update the View position with setY() method.
I tried to change it to getTop/setTop but it's not working properly, I suspect because getY is actually taking into account transformations and getTop is not (I guess animations are handled as transformations).
Any easy alternative for Froyo without modifying too much code?
This is the animation part:
animationSlideInDown = AnimationUtils.loadAnimation(this, R.anim.slide_out_down);
animationSlideOutUp = AnimationUtils.loadAnimation(this, R.anim.slide_in_up);
animationSlideInDown.setDuration(200);
animationSlideOutUp.setDuration(200);
animationSlideInDown.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
if (menuInitialPosition == -1) {
menuInitialPosition = menu.getY();
menuHeight = menu.getHeight();
} else {
menu.setY(menuInitialPosition);
}
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
menu.setY(menuInitialPosition);
}
});
animationSlideOutUp.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
menu.setY(-menuHeight);
}
});
This is the slide_out transition:
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="-100%"
android:toYDelta="0"
android:fillAfter="true"
android:fillEnabled="true"
android:duration="#android:integer/config_longAnimTime" />
Thanks!
If you want to get position of particular view on the screen than you can use :
int[] locationOnScreen = new int[2];
menu.getLocationOnScreen(locationOnScreen);
And for setting view to particular position you can use LayoutParams and set left and top margin for the view.

How to animate a layout in android?

In my Activity screen,half of the screen contain a layout.When Activity loaded it visible and after 10 seconds it will be get down slowly finally it will be not visible to user.But it get down slowly.How i can do it.Please can any one help me.
Thanking in Advance.
In your res\anim folder (create the folder if it's not there) create slide_out_down.xml and paste the following
<?xml version="1.0" encoding="utf-8"?>
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYDelta="0%p"
android:toYDelta="100%p"
android:duration="#android:integer/config_longAnimTime" />
to start the animation and hide the view use this
private void hideView(final View view){
Animation animation = AnimationUtils.loadAnimation(this, R.anim.slide_out_down);
//use this to make it longer: animation.setDuration(1000);
animation.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
view.setVisibility(View.GONE);
}
});
view.startAnimation(animation);
}
public void animateLayout(){
LinearLayout layout = findViewById(R.id.layoutId);
layout.animate().translationYBy(1000f).setDuration(50000);
}
The above code will make the view go invisible very slowly.
setDuration(50000) //change the number according to your need. It varies the speed of the layout.
You can use FragmentActivity and Fragment for this and add animation to the fragment
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="#android:anim/accelerate_interpolator">
<scale
android:fromXScale="1.0" android:toXScale="0.0"
android:fromYScale="1.0" android:toYScale="0.0"
android:pivotX="50%"
android:pivotY="50%"
android:duration="1000"
/>
try this:
// gone layout
collapse(recipientLayout);
//show layout
expand(recipientLayout);
public void expand(final LinearLayout v) {
v.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
final int targtetHeight = v.getMeasuredHeight();
/*if (v.isShown()) {
collapse(v);
} else */{
v.getLayoutParams().height = 0;
v.setVisibility(View.VISIBLE);
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
v.getLayoutParams().height = interpolatedTime == 1 ? LinearLayout.LayoutParams.WRAP_CONTENT
: (int) (targtetHeight * interpolatedTime);
v.requestLayout();
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (targtetHeight + 600));
v.startAnimation(a);
}
}
public void collapse(final LinearLayout v) {
final int initialHeight = v.getMeasuredHeight();
Animation a = new Animation() {
#Override
protected void applyTransformation(float interpolatedTime,
Transformation t) {
/*if (v.isShown()) {
collapse(v);
}*/
if (interpolatedTime == 1) {
v.setVisibility(View.GONE);
} else {
v.getLayoutParams().height = initialHeight
- (int) (initialHeight * interpolatedTime);
v.requestLayout();
}
}
#Override
public boolean willChangeBounds() {
return true;
}
};
a.setDuration((int) (v.getLayoutParams().height + 600));
v.startAnimation(a);
}

In android how to make a image grow from one point using animation?

In android how to make a image grow from one point using animation?
I mean to say is...i have a button ..and i want is when i click on that button my image must grow(ascending order) to grow bigger and bigger from that point ...and when again i click on that button again it must collapse gowing smaller and smaller to end at that point
Can any anybody help me in doing this using android animation?
i'm new to android
This can be achieved using View Animation utility. This scales the image from 100% to 140% for 1 sec
Place the following file in res/anim/scale.xml
<?xml version="1.0" encoding="utf-8"?>
<set android:shareInterpolator="false"
xmlns:android="http://schemas.android.com/apk/res/android">
<scale
android:interpolator="#android:anim/accelerate_decelerate_interpolator"
android:fromXScale="1.0"
android:toXScale="1.4"
android:fromYScale="1.0"
android:toYScale="1.4"
android:pivotX="50%"
android:pivotY="50%"
android:fillAfter="false"
android:duration="1000" />
</set>
Java code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final View view = findViewById(R.id.imageView1);
final Animation anim = AnimationUtils.loadAnimation(this, R.anim.scale);
Button button = (Button) findViewById(R.id.button1);
button.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
view.startAnimation(anim);
}
});
}
I would suggest you look at this SO post:
Android: Expand/collapse animation
public class DropDownAnim extends Animation {
int targetHeight;
View view;
boolean down;
public DropDownAnim(View view, int targetHeight, boolean down) {
this.view = view;
this.targetHeight = targetHeight;
this.down = down;
}
#Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
int newHeight;
if (down) {
newHeight = (int) (targetHeight * interpolatedTime);
} else {
newHeight = (int) (targetHeight * (1 - interpolatedTime));
}
view.getLayoutParams().height = newHeight;
view.requestLayout();
}
#Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
}
#Override
public boolean willChangeBounds() {
return true;
}
}
You would have to use that as an example as you want to apply it to your button.
Starting with Android 3.0, the preferred way of animating views is to
use the android.animation package APIs.These Animator-based classes change actual properties of the View object, ....
Or you can use a ViewPropertyAnimator for simple things - an image button that grows over a period of 1000ms to 1.4 x its size:
imageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
imageButton.animate().
scaleX(1.4f).
scaleY(1.4f).
setDuration(1000).start();
}
});

Categories

Resources