Search code examples
android-layoutanimationslidevisible

Layout snaps to visible (first time only) instead of slide animation


I'm creating a 2 row info bar in the bottom of the screen.

  • At first only the top row will be visible.
  • Press an 'expand' button, the 2nd row will slide up from below. Now both the rows are visible.
  • Pressing same button again, the bottom row slides down, and only the 1st row is visible.

This scenario is very common, and after checking different implementations, I've come to this simple one which works almost perfectly:

2 layouts in 1 > make bottom GONE > onClick - make bottom VISIBLE and apply slide up on entire Bar > onClick - apply slide down on Bar and make bottom GONE

Below is the onClick code:

mInfoBar = (RelativeLayout) mRootView.findViewById(R.id.infoBar); 
mInfoBottomRow = (RelativeLayout) mRootView.findViewById(R.id.infoBottomRow);

mBtnExpand.setOnClickListener(new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        if (mInfoBottomRow.getVisibility() == View.GONE) {
                            mInfoBottomRow.setVisibility(View.VISIBLE);

                            TranslateAnimation slideUp = new TranslateAnimation(0, 0, mInfoBottomRow.getHeight(), 0);
                            slideUp.setDuration(200);
                            mInfoBar.startAnimation(slideUp);
                        } else {

                            TranslateAnimation slideDown = new TranslateAnimation(0, 0, 0, mInfoBottomRow.getHeight());
                            slideDown.setDuration(200);

                            slideDown.setAnimationListener(new Animation.AnimationListener() {
                                @Override
                                public void onAnimationEnd(Animation animation) {
                                    mInfoBar.clearAnimation();
                                    mInfoBottomRow.setVisibility(View.GONE);
                                }

                                @Override
                                public void onAnimationRepeat(Animation animation) {
                                }

                                @Override
                                public void onAnimationStart(Animation animation) {
                                }
                            });

                            mInfoBar.startAnimation(slideDown);

                        }

                    }
                });

The problem is, the very first time the button is pressed, the info bar (with both top and bottom row) snaps to its position (without the sliding effect).

All other subsequent button press works perfectly...

2nd press - the bar slides down to show the top bar resting on the bottom of the screen and the bottom row gone.

3rd press - the bar slides up to show both top and bottom row.

and so on...

Can't understand why setVisibility(VISIBLE) is snapping to view only first time, or why the sliding effect is not showing the first time.

I'd rather not change the animation implementation since it's giving me desired effect all but once. So any insight within this will be really appreciated.


Solution

  • Your hiddenView's height is 0 for the first time as far as i guess. You should make visible your hiddenView in your layout. use

    android:visibility="visible" 
    

    instead of

    android:visibility="gone"
    

    in your hiddenView.

    Get the height and make it gone by following code:

    hiddenView.getViewTreeObserver().addOnGlobalLayoutListener(
       new ViewTreeObserver.OnGlobalLayoutListener(){
    
       @Override
       public void onGlobalLayout() {
    
           height = hiddenView.getHeight();
    
           hiddenView.getViewTreeObserver().removeGlobalOnLayoutListener( this );
           hiddenView.setVisibility( View.GONE );
      }
    });
    

    Use this height to animate.. :)