我有以下开关按钮(我是为 Android 2.3+ 创建的,所以不能使用 native 开关)。
使用以下 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 颜色将从“关闭”转换为“打开”(一个淡入,另一个淡出)
2) 同时白框会从一侧移动到另一侧
3) 在这个时间的一半时,v 符号将完全淡出
然后
4) 白框会稍微拉长背景,然后回到原来的位置。
5) 同时,背景会被拉伸(stretch)并恢复到原来的大小。
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) 下一步点击背景颜色立即改变,无淡入淡出。
有人知道我做错了什么吗?
最佳答案
我建议您使用 AnimationListener 来等待一个动画完成,然后再开始下一个动画,如果您想混合使用它们,请使用 http://nineoldandroids.com对于复杂的动画。
九老机器人是 Android 3.0 中引入的属性动画的向后兼容版本。
即使您设法使具有多个偏移量的多个动画在您的手机上运行,也不意味着它会在所有手机上运行。
我通过艰难的方式了解到,在我的应用程序经过完善并且在我的手机上一切正常后,我查看了其他一些(甚至是 4.x)手机,我不得不重构所有动画。
关于android - 我的 android 动画时间有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19737539/