Reputation: 70466
So imagine you have a parent relative layout with height set to wrap_content
. Inside this layout is another layout which is hidden by default. This is how I reveal it:
view.startAnimation(AnimationUtils.loadAnimation(context, R.anim.translate_in));
view.setVisibility(View.VISIBLE);
Here is the corresponding anim file. It basically moves the view from the bottom to the top.
<translate
android:duration="250"
android:fromXDelta="0"
android:fromYDelta="100%p"
android:toXDelta="0"
android:toYDelta="0"
android:fillAfter="true"/>
I expect the parent view to change its height according to the animation of the child view. However when the animation starts the parent view instantly shifts up while the child view is still animating. It feels like the setVisibility is called before the animation has finished.
So to solve this I would scale the height of the child from 0 to 100%, however I do not want a scale but a translate effect.
Any ideas how to approach this problem?
The layout is simple:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundColor="@color/grey">
<TextView/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:backgroundColor="@color/white"
android:visibility="GONE">
<TextView/>
</RelativeLayout>
</RelativeLayout>
Upvotes: 0
Views: 2323
Reputation: 4448
final RelativeLayout parent = null;//parent relative layout
final View child = null;//parent relative layout child
final int initParentHeight=parent.getHeight();
parent.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
parent.getViewTreeObserver().removeOnPreDrawListener(this);
int finalParentHeight = parent.getHeight();//get parent final height
final ViewGroup.LayoutParams layoutParams = parent.getLayoutParams();
ValueAnimator animator = ValueAnimator.ofInt(initParentHeight, finalParentHeight);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
layoutParams.height = (int) animation.getAnimatedValue();
parent.requestLayout();//animate height change
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;//reset parent layoutparams height to wrap_content
parent.requestLayout();
}
});
animator.setDuration(250);
animator.start();
return true;
}
});
child.setVisibility(View.VISIBLE);
Upvotes: 3