13

I got a ListView with items in it. When the user clicks an item it's height should scale to zero and all items below should scroll up. My code below doesnt work. With my code the item which was clicked scales right, but the items below dont scroll up, they stay at the same position. I've also tried it with an LinearLayout but there is the same problem.

There is an app which does this right. It's called Tasks.

This little image should explain the problem

My current implementation looks like this:

@Override
public void onItemClick(AdapterView<?> arg0, View v, final int index,
        long id) {
    Animation anim = AnimationUtils.loadAnimation(getActivity(),
            R.anim.scaleup);
    v.startAnimation(anim);
}

<set android:shareInterpolator="false" >
    <scale
        android:duration="700"
        android:fillAfter="false"
        android:fillBefore="false"
        android:fromXScale="1.0"
        android:fromYScale="1.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotY="0%"
        android:toXScale="1.0"
        android:toYScale="0.0" />
</set>

Basic Coder
  • 10,882
  • 6
  • 42
  • 75

3 Answers3

7

Here's a class I made (modified from source I found here) that may give you the functionality you want.

public class FadeUpAnimation extends Animation {

int mFromHeight;
View mView;

public FadeUpAnimation(View view) {
    this.mView = view;
    this.mFromHeight = view.getHeight();
}

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    int newHeight;
    newHeight = (int) (mFromHeight * (1 - interpolatedTime));
    mView.getLayoutParams().height = newHeight;
    mView.setAlpha(1 - interpolatedTime);
    mView.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;
}
}

Then this is how I'm using it

View tv = ...
Animation a = new FadeUpAnimation(tv);
a.setInterpolator(new AccelerateInterpolator());
a.setDuration(300);
tv.setAnimation(a);
tv.startAnimation(a);

You can play with it to see if you can get it to fit your needs.

Community
  • 1
  • 1
devnate
  • 744
  • 5
  • 8
  • hey, i was using this to collapse the listitem, but when the user presses undo I need to item to come back. Any way I could reverse the animation? I tried 'newHeight = (int) (mFromHeight * (1 + interpolatedTime));' Changing the minus to + but thats gives a strange effect – Zen Apr 14 '14 at 06:32
  • `interpolatedTime` interpolates from 0 to 1 so removing `0 -` should yield the opposite effect. You'll also have to change `mFromHeight` (probably renamed to `mToHeight`) to initialize to the view's natural height. e.g. `this.mToHeight = view.getMeasuredHeight();` – devnate Apr 24 '14 at 03:01
  • One thing: If height is set to 0 the view will take it's full height again (at least with my code), so do something like `mView.getLayoutParams().height = Math.max(newHeight, 1);` – paulgavrikov Aug 24 '14 at 13:29
  • Great! But how can I zoom out list item content too? – Konstantin Konopko Oct 22 '14 at 16:52
3

Will you use the clicked item again? If not, then you could

  1. Wait until the animation finishes
  2. Delete the item from wherever you store the underlaying data
  3. Then call the notifyDataSetChanged() method of your listadapter
Balázs Édes
  • 13,452
  • 6
  • 54
  • 89
  • this is correct. use an animation listener attached to the animation for "onAnimationEnd" and then do as suggested. – Alex Hart Sep 10 '13 at 12:45
  • This does not answer the question - the lower views will not move up as the target view scales to nothing, they will only snap into place once the animation finishes. – Tom Nov 25 '14 at 23:01
0

The Android don't act like HTML, when you change the width, height or visibility in a view, the other views don't update theirs positions. If you need to do that, you must update all the listview and your views inside, individually. This is a complex code to do.

Bruno Nardini
  • 461
  • 5
  • 13