2013-11-02 33 views
1

我有下面的開關按鈕(我爲Android 2.3+創建這個,所以不能使用本地開關)。我的android動畫時機有什麼問題?

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顏色將從「關閉」轉換爲「開啓」(其中一個會淡入)和其他淡出)

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

請解釋一下實際發生的事情。 –

+1

**但實時**,動畫是完全不同於我想要的。 1)第一次點擊白框後消失 - 我猜我的轉換是錯誤的。 2)下一次點擊bg顏色變化,不會淡入淡出。 –

+0

我認爲bg的變化覆蓋了它的一切。 –

回答

2

我建議您使用AnimationListener等待一個動畫完成,然後再開始下一個動畫,如果要混合它們,請將http://nineoldandroids.com用於複雜動畫。

九舊Android是在Android 3.0中引入的屬性動畫的向後兼容版本。

即使您設法在您的手機上製作具有多個偏移量的多個動畫,但這並不表示它可以在所有手機上使用。

我已經瞭解到,在我的應用程序打磨完畢並且手機上的所有內容都正常工作後,我看到了其他一些(甚至是4.x)手機,並且我不得不重構所有動畫。