次のスイッチ ボタンがあります (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) 背景色は「オフ」から「オン」に変換されます (1 つはフェードインし、もう 1 つはフェードアウトします)。
2) 同時に、白いボックスが一方の側から他方の側に移動します
3) この時間の半分で、v サインは完全にフェードアウトします。
それで
4) 白いボックスは背景を少し引き伸ばし、元の位置に戻ります。
5) 同時に背景が引き伸ばされ、元のサイズに戻ります。
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 の色を一度にクリックすると、フェードインとフェードアウトはありません。
誰かが私が間違っていることを知っていますか?