6

I'm trying to make a really simple slide up list view, which is displayed when a user clicks on a button at the bottom of the screen. Here's how it should look:

sliding thingy

And a complete implementation in HTML/JS http://jsbin.com/utAQOVA/1/edit

I've tried to use RelativeLayout to position the list just below the button, and put that whole thing into a wrapper and then animate that up/down (same as in the JSBin above).

The problem is that the bottom part which isn't visible in the beginning is somehow clipped, even if I slide it up. Evern if I initially show a portion of the list as the screenshow below shows, the bottom part gets clipped when it moves up and only the part that was initially visible is displayed.

clipping

What would be a proper approach to do this kind of animation?

Here's a relevant portion of the layout

Edit: after a brief discussion (in the comments of the accepted answer) I've solved this by removing the wrapping LinearLayout around the part that is animated and I simply changed height of the ListView, which pushes the button up.

Jakub Arnold
  • 85,596
  • 89
  • 230
  • 327

2 Answers2

4

The problem you have might come form how ListView does its own layout, basically it fits itself to the size available on screen and paints that part and since you create the ListView without Height or very small height that the size it keeps. You can solve this with two approaches:

  1. Replaces the ListView with a simple LinearLayout - filled with all you list items, I would do this if you don't have many items on the list - then the advantages of a ListView over a simple LinearLayout is negligible.
  2. Use a ValueAnimator and update the position & height property of the ListView while animating.

Adapted from a post I mentioned in the comments a ValueAnimator should look like this:

ValueAnimator va = ValueAnimator.ofInt(0, height);
    va.setDuration(700);
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer value = (Integer) animation.getAnimatedValue();
            v.getLayoutParams().height = value.intValue();
            v.setTranslationY(-value.intValue());
            v.requestLayout();
        }
    });
  • I'm not sure if using setTranslationY is the right way for this question or maybe you should use a negative marginTop value (depends on the layout)
Raanan
  • 4,777
  • 27
  • 47
  • I'm already using a TransitionAnimator for the movement, is there a way that I can _merge_ it with the ValueAnimator to run both of the animations at the same time? – Jakub Arnold Nov 03 '13 at 14:49
  • I would only use the ValueAnimator, check this thread for an example: http://stackoverflow.com/questions/11935216/animation-of-height-of-linearlayout-container-with-valueanimator – Raanan Nov 03 '13 at 14:56
  • 1
    I think I understand the problem now. I've changed my app to use only `ValueAnimator`, but even if I set `heigth` of the `ListView` to some stupidly arbitrary high number (like 10000) it doesn't change it's height, but it does change the Y position. – Jakub Arnold Nov 03 '13 at 15:15
  • I'll joins @ssantos request to see the layout, and also is the top layout height set to match_parent ? – Raanan Nov 03 '13 at 15:25
  • Added link to the bottom of the question. – Jakub Arnold Nov 03 '13 at 15:53
  • in your value animator try changing the height of the ListWrapper also or calling requestLayout() on the ListWrapper, if this works, then you might just need to change the layout. – Raanan Nov 03 '13 at 16:18
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40462/discussion-between-raanan-and-jakub-arnold) – Raanan Nov 03 '13 at 16:20
1

The animation you're looking for would look like this.-

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_longAnimTime"
    android:fromYDelta="100%p"
    android:toYDelta="0" />

You can run it storing it an animation xml resource, and doing.-

Animation anim = AnimationUtils.loadAnimation(this, R.anim.animId);
yourView.startAnimation(anim);
ssantos
  • 16,001
  • 7
  • 50
  • 70
  • I've tried doing `var animation = new TranslateAnimation(0, 0, -600, 0); animation.Duration = 1000; animation.FillAfter = true;`, does that achieve the same thing? Because with that the bottom part of the view is still clipped. – Jakub Arnold Nov 03 '13 at 14:44
  • Mmh could you post your layout xml? I'm guessing there's a parent view clipping your relativelayout. You could try and `setClipChildren` to false. – ssantos Nov 03 '13 at 14:45
  • Added link to the bottom of the question – Jakub Arnold Nov 03 '13 at 15:50