如何使用AnimatorSet实现初始宽度为0dp的View宽度动画?
The issue with the official sample code is that <animator> creates a ValueAnimator, which only animates a numerical value but doesn't automatically apply it to your View's layout width. Additionally, using propertyName="width" with ObjectAnimator won't work because the View's setWidth() method affects the minimum width, not the actual layout width controlled by LayoutParams.
Here are two reliable approaches to achieve the desired animation:
Approach 1: Use ValueAnimator with Update Listener (Minimal Code)
Step 1: Define the Animator XML
Create res/animator/width_expand.xml:
<animator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:valueFrom="0" android:valueTo="@dimen/target_width" <!-- Define this in res/values/dimens.xml as e.g., 200dp --> android:valueType="intType" />
Step 2: Load and Apply the Animator in Code
View yourView = findViewById(R.id.your_view); Animator animator = AnimatorInflater.loadAnimator(this, R.animator.width_expand); animator.addUpdateListener(animation -> { int newWidth = (int) animation.getAnimatedValue(); ViewGroup.LayoutParams params = yourView.getLayoutParams(); params.width = newWidth; yourView.setLayoutParams(params); }); // For AnimatorSet, load the set and attach listeners to child animations AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator/your_animator_set); for (Animator anim : set.getChildAnimations()) { if (anim instanceof ValueAnimator) { ((ValueAnimator) anim).addUpdateListener(animation -> { int newWidth = (int) animation.getAnimatedValue(); ViewGroup.LayoutParams params = yourView.getLayoutParams(); params.width = newWidth; yourView.setLayoutParams(params); }); } } animator.start(); // Or set.start();
Step 3: Set Initial Width in Layout
Ensure your View starts with 0dp width:
<View android:id="@+id/your_view" android:layout_width="0dp" android:layout_height="wrap_content" <!-- other attributes --> />
Approach 2: Custom View with ObjectAnimator (XML-First)
If you prefer less code in your Activity/Fragment, create a custom View that exposes a layoutWidth property:
Step 1: Create Custom View
public class AnimatedWidthView extends View { public AnimatedWidthView(Context context) { super(context); } public AnimatedWidthView(Context context, AttributeSet attrs) { super(context, attrs); } public void setLayoutWidth(int width) { ViewGroup.LayoutParams params = getLayoutParams(); params.width = width; setLayoutParams(params); } public int getLayoutWidth() { return getLayoutParams().width; } }
Step 2: Define ObjectAnimator XML
Create res/animator/width_anim_object.xml:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:propertyName="layoutWidth" android:valueFrom="0" android:valueTo="@dimen/target_width" android:valueType="intType" />
Step 3: Use in Layout and Start Animation
<com.yourpackage.AnimatedWidthView android:id="@+id/animated_view" android:layout_width="0dp" android:layout_height="wrap_content" />
In code:
AnimatedWidthView animatedView = findViewById(R.id.animated_view); Animator animator = AnimatorInflater.loadAnimator(this, R.animator.width_anim_object); animator.setTarget(animatedView); animator.start();
For AnimatorSet, include the ObjectAnimator in your set XML and load it as usual.
内容的提问来源于stack exchange,提问作者kc_dev

