如何以动画方式设置为wrap_content?

7
使用ValueAnimator动画实现wrap_content可能吗?似乎只适用于常数值。
public static void valueAnimate(final View obj, int from, int to, Interpolator interpolator, long duration, long delay){

    ValueAnimator anim = ValueAnimator.ofInt(from, to);
    anim.setInterpolator(interpolator == null ? DEFAULT_INTERPOLATOR : interpolator);
    anim.setDuration(duration);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            Integer value = (Integer) animation.getAnimatedValue();
            obj.getLayoutParams().height = value.intValue();
            obj.requestLayout();
        }
    });
    anim.setStartDelay(delay);
    anim.start();
}

我该如何将to参数传递为wrap_content
Animator.valueAnimate(mapUtilsContainer, CURR_MAPUTILC_H, 800, OVERSHOOT, 300, 0);

1
你尝试过使用animateLayoutChanges吗?https://proandroiddev.com/the-little-secret-of-android-animatelayoutchanges-e4caab2fddec - Gavin Wright
不是我要找的。这只是在玩弄布局参数和默认动画。我需要使用ValueAnimation - Esteban Rincon
你是想要展开一个原本隐藏的视图吗? - noahutz
@noahutz 是的,它是一个RelativeLayout,可以在0和wrap_content之间切换。 - Esteban Rincon
2个回答

7
你可以这样做。传递一个最初设置为gone的视图。
public static void expand(final View view) {
    view.measure(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
    final int targetHeight = view.getMeasuredHeight();

    // Set initial height to 0 and show the view
    view.getLayoutParams().height = 0;
    view.setVisibility(View.VISIBLE);

    ValueAnimator anim = ValueAnimator.ofInt(view.getMeasuredHeight(), targetHeight);
    anim.setInterpolator(new AccelerateInterpolator());
    anim.setDuration(1000);
    anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            layoutParams.height = (int) (targetHeight * animation.getAnimatedFraction());
            view.setLayoutParams(layoutParams);
        }
    });
    anim.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            // At the end of animation, set the height to wrap content
            // This fix is for long views that are not shown on screen
            ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
            layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
        }
    });
    anim.start();
}

这对于单个TextView对我有用,但当我将它用于包含多个TextView的LinearLayout上时,动画高度大于实际wrap_content高度!它会动画到超出大小的高度,然后弹回到实际高度。 - Bip901
已解决!请参见此答案:https://stackoverflow.com/a/59818318/7812339 - Bip901

7
一个简单的解决方法是在包含组件的布局中使用android:animateLayoutChanges属性。这适用于Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN (Android 4.3)。 例如,我有一个EditText需要从特定高度更改为wrap_content。
  1. Add the android:animateLayoutChanges attribute to my ScrollView.

      < ScrollView
        ...
        android:animateLayoutChanges="true">
    
  2. Add this in your onCreateView()

    scrollView.layoutTransition.enableTransitionType(LayoutTransition.CHANGING)

然后您将看到EditText高度的相对平稳的变化。
  1. Code to change the height of EditText to wrap_content

      fun wrapText() {
          val layoutParams = this.layoutParams
          layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT
          this.layoutParams = layoutParams
          isExpanded = false
      }
    

1
正是我想要的,不知道这个存在!非常有帮助的答案! - Toufic Batache

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接