我的android动画时机有什么问题?

时间:2013-11-02 00:23:33

标签: android android-layout animation layout android-animation

我有以下切换按钮(我为Android 2.3+创建此按钮,因此无法使用本机切换)。

enter image description here

使用以下XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/settingsSwitchMainLayout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:clickable="true" >

    <ImageView
        android:id="@+id/switch_bg2"
        android:layout_width="90dp"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_centerInParent="true"
        android:layout_centerVertical="true"
        android:src="@drawable/switch_bg_off" />

    <RelativeLayout
        android:id="@+id/switch_handle"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:layout_alignParentRight="true"
        android:layout_marginTop="7dp"
        android:background="@drawable/switch_handle"
        android:padding="0dp" >

        <ImageView
            android:id="@+id/switch_v"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="17dp"
            android:layout_marginTop="14dp"
            android:src="@drawable/switch_v"
            android:visibility="visible" />
    </RelativeLayout>

</RelativeLayout>

以下代码:

    public class SettingsSwitchView extends RelativeLayout {

        private enum SwitchModes {
            CHECKED, UNCHECKED
        }

        private static final int FULL_DURATION = 18000;

        private ImageView mSwitchBg2;
        private RelativeLayout mSwitchHandle;
        private ImageView mSwitchV;
        private NinePatchDrawable mBgTransition;

        private boolean isChecked;

        public SettingsSwitchView(Context context, AttributeSet attrs) {
            super(context, attrs);
            inflater = LayoutInflater.from(context);
            inflater.inflate(R.layout.settings_switch, this);
            initMemebers();

            isChecked = true; // read from config file
            setOnClickListeners();
        }

        private void setOnClickListeners() {
            mSwitchBg2.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    isChecked = !isChecked;
                    SwitchModes switchMode = (isChecked)? SwitchModes.CHECKED : SwitchModes.UNCHECKED;
                    anim_first(switchMode);
                }
            });
        }


        private void anim_first(SwitchModes mode)
        {
            AnimationSet bgAnimation = new AnimationSet(true);

            //bg fade out
            AlphaAnimation alpha_bg_0_50 = getBgAlphafirst(mode);

            //fade_V
            AlphaAnimation alpha_V_0_100 = getVAlphafirst(mode);

            mSwitchV.startAnimation(alpha_V_0_100);

            //slide 
            Animation slide_box_0_100 = getSlideFirst(mode);

            mSwitchHandle.startAnimation(slide_box_0_100);


            //bg fade in
            AlphaAnimation alpha_bg_50_100 = getBgAlphaSecond();
            bgAnimation.addAnimation(alpha_bg_0_50);
            bgAnimation.addAnimation(alpha_bg_50_100);
            mSwitchBg2.startAnimation(bgAnimation);

            //extra slide, stretch
            mSwitchBg2.startAnimation(getExtraScale(mode));
            mSwitchHandle.startAnimation(getExtraSlide(mode));
        }

public class SettingsSwitchView extends RelativeLayout {

    private enum SwitchModes {
        CHECKED, UNCHECKED
    }

    private static final int FULL_DURATION = 18000;

    private static final int TRANSITION_DURATION = 180;
    private static final int ALPHA_DURATION = 180;
    //private static final int BG_TRANSITION_TIME = 40;
    private LayoutInflater inflater;

    //private RelativeLayout mSwitchBg;
    private ImageView mSwitchBg2;
    private RelativeLayout mSwitchHandle;
    private ImageView mSwitchV;
    // private TransitionDrawable mBgTransition;
    private NinePatchDrawable mBgTransition;

    private boolean isChecked;

    public SettingsSwitchView(Context context, AttributeSet attrs) {
        super(context, attrs);
        inflater = LayoutInflater.from(context);
        inflater.inflate(R.layout.settings_switch, this);
        initMemebers();

        isChecked = true; // read from config file
        setOnClickListeners();
    }

    private void setOnClickListeners() {
        mSwitchBg2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isChecked = !isChecked;
                SwitchModes switchMode = (isChecked)? SwitchModes.CHECKED : SwitchModes.UNCHECKED;
                anim_first(switchMode);
            }
        });
    }


    private void anim_first(SwitchModes mode)
    {
        AnimationSet bgAnimation = new AnimationSet(true);

        //bg fade out
        AlphaAnimation alpha_bg_0_50 = getBgAlphafirst(mode);

        //fade_V
        AlphaAnimation alpha_V_0_100 = getVAlphafirst(mode);

        mSwitchV.startAnimation(alpha_V_0_100);

        //slide 
        Animation slide_box_0_100 = getSlideFirst(mode);

        mSwitchHandle.startAnimation(slide_box_0_100);


        //bg fade in
        AlphaAnimation alpha_bg_50_100 = getBgAlphaSecond();
        bgAnimation.addAnimation(alpha_bg_0_50);
        bgAnimation.addAnimation(alpha_bg_50_100);
        mSwitchBg2.startAnimation(bgAnimation);

        //extra slide, stretch
        mSwitchBg2.startAnimation(getExtraScale(mode));
        mSwitchHandle.startAnimation(getExtraSlide(mode));
    }

    private TranslateAnimation getExtraSlide(SwitchModes mode) {

        final TranslateAnimation translate;

        switch (mode) {
        case CHECKED: {
            translate = new TranslateAnimation(Animation.RELATIVE_TO_SELF, -15, Animation.RELATIVE_TO_SELF, -5, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
            break;
        }
        default:
        case UNCHECKED: {
            translate =  new TranslateAnimation(Animation.RELATIVE_TO_SELF, -60, Animation.RELATIVE_TO_SELF, -70, Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0);
            break;
        }
        }

        translate.setDuration(FULL_DURATION/4);
        translate.setStartOffset(FULL_DURATION);

        return translate;
    }


    private ScaleAnimation getExtraScale(SwitchModes mode) {
        final ScaleAnimation scaleAnimation;

        switch (mode) {
        case CHECKED: {
            scaleAnimation = new ScaleAnimation(1, (float)1.1, 1, 1, Animation.RELATIVE_TO_SELF, (float)0.1, Animation.RELATIVE_TO_SELF, (float)0.5);
            break;
        }
        default:
        case UNCHECKED: {
            scaleAnimation = new ScaleAnimation(1, (float)1.1, 1, 1, Animation.RELATIVE_TO_SELF, (float)0.9, Animation.RELATIVE_TO_SELF, (float)0.5);
            break;
        }
        }

        scaleAnimation.setDuration(FULL_DURATION/4);
        scaleAnimation.setStartOffset(FULL_DURATION);

        return scaleAnimation;
    }


    private AlphaAnimation getVAlphafirst(SwitchModes mode) {
        AlphaAnimation alpha;
        switch (mode) {
        case CHECKED: {
            mSwitchV.setVisibility(View.VISIBLE);
            alpha = new AlphaAnimation(0, 1);
            break;
        }
        default:
        case UNCHECKED: {
            mSwitchV.setVisibility(View.GONE);
            alpha = new AlphaAnimation(1, 0);
            break;
        }
        }
        alpha.setDuration(FULL_DURATION);
        alpha.setFillAfter(true);
        return alpha;
    }

    private AlphaAnimation getBgAlphafirst(SwitchModes mode) {
        AlphaAnimation alpha;
        alpha = new AlphaAnimation(1, (float) 0.5);
        alpha.setDuration(FULL_DURATION/2);

        switch (mode) {
        case CHECKED: {
            mSwitchBg2.setImageDrawable(getResources().getDrawable(R.drawable.switch_bg_on));
            break;
        }
        case UNCHECKED: {
            mSwitchBg2.setImageDrawable(getResources().getDrawable(R.drawable.switch_bg_off));
            break;
        }
        }
        return alpha;

    }

    private AlphaAnimation getBgAlphaSecond() {
        AlphaAnimation alpha;
        alpha = new AlphaAnimation((float) 0.5, 1);
        alpha.setDuration(FULL_DURATION/2);
        alpha.setStartOffset(FULL_DURATION/2);
        return alpha;
    }

    private Animation getSlideFirst(SwitchModes mode) {
        Animation aniamtion;
        switch (mode) {
        case CHECKED: {
            aniamtion = android.view.animation.AnimationUtils.loadAnimation(
                    AppService.getAppContext(), com.myApp.R.anim.slide_to_right);
            break;
        }
        default:
        case UNCHECKED: {
            aniamtion = android.view.animation.AnimationUtils.loadAnimation(
                    AppService.getAppContext(), com.myApp.R.anim.slide_to_left);
            break;
        }
        }

        aniamtion.setDuration(FULL_DURATION);
        aniamtion.setInterpolator(new AccelerateInterpolator());
        aniamtion.setFillAfter(true);
        return aniamtion;
    }

    private void initMemebers() {
        //mSwitchBg = (RelativeLayout) findViewById(R.id.switch_bg);
        mSwitchBg2 = (ImageView) findViewById(R.id.switch_bg2);

        mSwitchHandle = (RelativeLayout) findViewById(R.id.switch_handle);
        mSwitchV = (ImageView) findViewById(R.id.switch_v);
    }
}

我正在使用Android动画制作这个动画:

1)bg颜色将从&#34; off&#34;到&#34; on&#34; (一个会淡入,另一个会淡出)

2)同时白框将从一侧移动到另一侧

3)在这段时间的一半时间,v符号将完全淡出

然后

4)白框将拉伸bg并返回其位置。

5)同时,bg将被拉伸并恢复其大小。

slide_to_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set
     xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator">
    <translate
        android:fromXDelta="-15%"
        android:toXDelta="-60%">

    </translate>
</set>

但实时,动画与我想要的完全不同。

1)首次点击后白色框消失 - 我认为bg更改覆盖了它上面的所有内容。

2)接下来立即点击bg颜色变化,没有淡入和淡出。

有人知道我做错了什么吗?

1 个答案:

答案 0 :(得分:2)

我建议您在开始下一个动画之前使用AnimationListener等待一个动画完成,如果要混合它们,请使用http://nineoldandroids.com进行复杂的动画制作。

Nine Old Androids是Android 3.0中引入的属性动画的向后兼容版本。

即使您设法在手机上制作多个具有多种偏移效果的动画,也不意味着它可以在所有手机上使用。

我学到了很难的方法,在我的应用程序被打磨并且手机上的一切正常后,我看了一些其他(甚至4.x)手机,我不得不重构所有动画。