我有以下切换按钮(我为Android 2.3+创建此按钮,因此无法使用本机切换)。
使用以下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颜色变化,没有淡入和淡出。
有人知道我做错了什么吗?
答案 0 :(得分:2)
我建议您在开始下一个动画之前使用AnimationListener等待一个动画完成,如果要混合它们,请使用http://nineoldandroids.com进行复杂的动画制作。
Nine Old Androids是Android 3.0中引入的属性动画的向后兼容版本。
即使您设法在手机上制作多个具有多种偏移效果的动画,也不意味着它可以在所有手机上使用。
我学到了很难的方法,在我的应用程序被打磨并且手机上的一切正常后,我看了一些其他(甚至4.x)手机,我不得不重构所有动画。