Android 动画布局的同级直到动画完成后才进行动画

Android 动画布局的同级直到动画完成后才进行动画,android,android-layout,android-animation,android-view,Android,Android Layout,Android Animation,Android View,我正在使用Animator()从视图组中添加和删除视图。当我移除它们时,视图将显示动画(它是“向上滑动”运动),但其他子对象在动画完成之前不会对动画做出反应(向上滑动以占据空间)。我这样假设是因为我使用的是在动画之后才将动画视图设置为“消失”。当动画视图滑出时,是否有方法使其他视图向上滑动?这是相关代码 AnimatorListener mCloseListener = new AnimatorListener() { @Override public void onAnimat

我正在使用Animator()从视图组中添加和删除视图。当我移除它们时,视图将显示动画(它是“向上滑动”运动),但其他子对象在动画完成之前不会对动画做出反应(向上滑动以占据空间)。我这样假设是因为我使用的是在动画之后才将动画视图设置为“消失”。当动画视图滑出时,是否有方法使其他视图向上滑动?这是相关代码

AnimatorListener mCloseListener = new AnimatorListener() {
        @Override public void onAnimationEnd(Animator arg0) {
            viewToAnimate.setVisibility(View.GONE);
        }
        @Override public void onAnimationStart(Animator arg0) { }
        @Override public void onAnimationCancel(Animator arg0) { }
        @Override public void onAnimationRepeat(Animator arg0) { }
    };

viewToAnimate.animate().translationYBy(-viewToAnimate.getMeasuredHeight())
            .setDuration(ANIMATION_DURATION).setInterpolator(new DecelerateInterpolator()).setListener(
                    mCloseListener);

首先,您没有使用
Animator
,但是,这有点不同,您正在尝试为视图转换设置动画。从定义上看,很明显它是在布局后应用的,所以我假设其他视图/视图不参与,也不关心该属性值

我认为,您需要设置
页边距
或视图的其他位置的动画,以使ViewGroup了解配置更改。我认为它可以用,但需要多一点编码

这里有一些简单的例子。假设通过向上/向下滑动添加/删除按钮应根据以下布局设置动画:

<RelativeLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    <Button
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_height"
        android:layout_alignParentTop="true"
        android:id="@+id/btn1"
        android:layout_weight="1"
        android:text="Button 1"
        android:onClick="buttonClickListener" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_height"
        android:layout_below="@id/btn1"
        android:id="@+id/btn2"
        android:layout_weight="1"
        android:text="Button 2: Remove button 1"
        android:onClick="buttonClickListener" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_height"
        android:layout_below="@id/btn2"
        android:id="@+id/btn3"
        android:layout_weight="1"
        android:text="Button 3: Remove button 2"
        android:onClick="buttonClickListener" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="@dimen/button_height"
        android:layout_below="@id/btn3"
        android:id="@+id/btn4"
        android:layout_weight="1"
        android:text="Button 4: add removed button"
        android:onClick="buttonClickListener" />
</RelativeLayout>

然后,活动可能如下所示:

public class MyActivity extends Activity implements Animator.AnimatorListener {

    private static final String TAG = "MyActivity";

    /** Queue to manage removed buttons */
    private LinkedBlockingDeque<Integer> mRemovedButtonDeque = new LinkedBlockingDeque<Integer>();
    /** Distance view should be moved up and down, from resources */
    private int mMovingDistance = 0;
    /** Animators to be used */
    private ObjectAnimator mMarginAnimator;
    /** Duration of all animations */
    private static final int ANIMATION_DURATION = 1000;
    /** Id of currently adding view */
    private int mAddingId = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Show the layout with the test view
        setContentView(R.layout.main);

        mMovingDistance = getResources().getDimensionPixelSize(R.dimen.button_height);

        mMarginAnimator = new ObjectAnimator().setDuration(ANIMATION_DURATION);
        mMarginAnimator.setInterpolator(new DecelerateInterpolator());

        mMarginAnimator.addListener(this);
    }

    @Override
    public void onAnimationStart(final Animator animation) {
        // nothing to do here
    }

    @Override
    public void onAnimationEnd(final Animator animation) {
        if (mAddingId == 0) {
            final Integer removingViewId = mRemovedButtonDeque.peek();

            if (removingViewId != null) {
                findViewById(removingViewId).setVisibility(View.GONE);
            }
        }
    }

    @Override
    public void onAnimationCancel(final Animator animation) {
        // nothing to do here
    }

    @Override
    public void onAnimationRepeat(final Animator animation) {
        // nothing to do here
    }

    /**
     * Listener for buttons click
     *
     * @param clickedButton {@link View}
     */
    public void buttonClickListener(final View clickedButton) {
        final int buttonId = clickedButton.getId();
        MarginAnimatorHelper animator = null;

        switch (buttonId) {
            case R.id.btn1:
                // nothing to do here
                break;

            case R.id.btn2:
                animator = new MarginAnimatorHelper((Button) findViewById(R.id.btn1));
                mRemovedButtonDeque.add(R.id.btn1);
                mMarginAnimator.setIntValues(0, -mMovingDistance);
                break;

            case R.id.btn3:
                if (findViewById(R.id.btn1).getVisibility() != View.VISIBLE) {
                    animator = new MarginAnimatorHelper((Button) findViewById(R.id.btn2));
                    mRemovedButtonDeque.add(R.id.btn2);
                    mMarginAnimator.setIntValues(0, -mMovingDistance);
                }
                break;

            case R.id.btn4:
                final Integer removedId = mRemovedButtonDeque.pollLast();

                if (removedId != null) {
                    final Button removedButton = (Button) findViewById(removedId);

                    animator = new MarginAnimatorHelper(removedButton);
                    removedButton.setVisibility(View.VISIBLE);
                    mMarginAnimator.setIntValues(-mMovingDistance, 0);
                }
                break;
        }

        if (animator != null) {
            mMarginAnimator.setTarget(animator);
            mMarginAnimator.setPropertyName(MarginAnimatorHelper.PROPERTY_NAME);
            mMarginAnimator.start();
        }
    }

    /**
     * This view will manages view removing
     * and act as {@link ObjectAnimator} target
     */
    private static class MarginAnimatorHelper {
        /** Name of the property to be animated */
        private static final String PROPERTY_NAME = "topMargin";

        /** Button to be animated */
        private final Button mButton;

        /**
         * Default constructor
         *
         * @param button {@link Button} to be animated
         */
        public MarginAnimatorHelper(final Button button) {
            mButton = button;
        }

        /**
         * Setter for property 'topMargin'
         *
         * @param margin new value of the property
         */
        public void setTopMargin(final int margin) {
            final ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mButton.getLayoutParams();

            params.topMargin = margin;
            mButton.setLayoutParams(params);
        }
    }
}
公共类MyActivity扩展活动实现Animator.AnimatorListener{
私有静态最终字符串TAG=“MyActivity”;
/**用于管理已删除按钮的队列*/
private LinkedBlockingDeque mRemovedButtonDeque=new LinkedBlockingDeque();
/**距离视图应该从资源中上下移动*/
私有距离=0;
/**动画师将被使用*/
私有对象动画师mMarginAnimator;
/**所有动画的持续时间*/
私有静态最终整数动画\u持续时间=1000;
/**当前添加视图的Id*/
私有int-mAddingId=0;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//使用测试视图显示布局
setContentView(R.layout.main);
mMovingDistance=getResources().getDimensionPixelSize(R.dimen.按钮高度);
mMarginAnimator=newObjectAnimator().setDuration(动画持续时间);
mMarginAnimator.setInterpolator(新减速插补器());
mMarginAnimator.addListener(此);
}
@凌驾
动画开始时的公共无效(最终动画制作){
//这里没什么可做的
}
@凌驾
onAnimationEnd上的公共无效(最终动画制作){
如果(mAddingId==0){
最终整数removingViewId=mRemovedButtonDeque.peek();
如果(removingViewId!=null){
findViewById(removingViewId).setVisibility(View.GONE);
}
}
}
@凌驾
动画取消上的公共无效(最终动画制作){
//这里没什么可做的
}
@凌驾
AnimationRepeat(最终Animator动画)上的公共无效{
//这里没什么可做的
}
/**
*按钮的侦听器单击
*
*@param clicked按钮{@link View}
*/
公共作废按钮ClickListener(最终视图单击按钮){
final int buttonId=clickedButton.getId();
MarginAnimatorHelper animator=null;
开关(按钮NID){
案例R.id.btn1:
//这里没什么可做的
打破
案例R.id.btn2:
animator=新的MarginAnimatorHelper((按钮)findviewbyd(R.id.btn1));
mRemovedButtonDeque.add(R.id.btn1);
mArginaniMator.SetIntValue(0,-mMovingDistance);
打破
案例R.id.btn3:
if(findViewById(R.id.btn1).getVisibility()!=View.VISIBLE){
animator=新的MarginAnimatorHelper((按钮)findviewbyd(R.id.btn2));
mRemovedButtonDeque.add(R.id.btn2);
mArginaniMator.SetIntValue(0,-mMovingDistance);
}
打破
案例R.id.btn4:
最终整数removedId=mRemovedButtonDeque.pollLast();
如果(removedId!=null){
最终按钮removedButton=(按钮)findViewById(removedId);
animator=新的MarginAnimatorHelper(removedButton);
removedButton.setVisibility(View.VISIBLE);
mMarginAnimator.setIntValues(-mMovingDistance,0);
}
打破
}
if(animator!=null){
mMarginAnimator.setTarget(动画师);
mMarginAnimator.setPropertyName(MarginAnimatorHelper.PROPERTY_NAME);
mMarginAnimator.start();
}
}
/**
*此视图将管理视图删除
*并充当{@link ObjectAnimator}目标
*/
私有静态类MarginAnimatorHelper{
/**要设置动画的属性的名称*/
私有静态最终字符串属性\u NAME=“topMargin”;
/**要设置动画的按钮*/
私人最终按钮姆布顿;
/**
*默认构造函数
*
*@param按钮{@link按钮}要设置动画
*/
公共边缘图像辅助对象(最终按钮){
mButton=按钮;
}
/**
*属性“topMargin”的设置器
*
*@param margin属性的新值
*/
公共无效setTopMargin(最终整数保证金){
final ViewGroup.MarginLayoutParams params=(ViewGroup.MarginLayoutParams)mButton.getLayoutParams();
params.topMargin=页边距;
mButton.setLayoutParams(参数);
}
}
}
有一个内部类
MarginAnimatorHelper
,它完成所有主要工作:更改影响其他布局元素的真实视图布局参数