2013-10-26 53 views
1

我正在使用NineOldAndroid庫執行動畫。動畫API < = 10的效果很好。但對於API> 10,應用程序部隊將關閉。這是我的代碼:NineOldAndroids動畫不適用於API> 10

import static com.nineoldandroids.view.ViewPropertyAnimator.animate; 
import android.content.Intent; 
import android.graphics.Canvas; 
import android.graphics.PixelFormat; 
import android.os.Build; 
import android.os.Bundle; 
import android.view.KeyEvent; 
import android.view.View; 
import android.view.ViewTreeObserver.OnGlobalLayoutListener; 
import android.view.WindowManager; 
import android.widget.ImageView; 
import android.widget.LinearLayout; 
import android.widget.RelativeLayout; 
import android.widget.TextView; 

import com.actionbarsherlock.app.ActionBar; 
import com.actionbarsherlock.view.MenuItem; 
import com.nineoldandroids.animation.Animator; 
import com.nineoldandroids.animation.Animator.AnimatorListener; 
import com.nineoldandroids.animation.ObjectAnimator; 

public class ActivityActualMain extends SherlockActivity { 
    LinearLayout container1, container2; 
    RelativeLayout viewTree; 
    ImageView image, image1, image2; 
    TextView tv, tv1, tv2, tv3, tv4; 
    ObjectAnimator anim; 



@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    final int duration = 2000; 
    setContentView(R.layout.activity_actual_main); 

    ActionBar bar = getSupportActionBar(); 
    bar.setDisplayHomeAsUpEnabled(true); 
    bar.setBackgroundDrawable(getResources().getDrawable(
      R.drawable.red_actionbar)); 
    viewTree = (RelativeLayout) findViewById(R.id.viewTree); 
    container1 = (LinearLayout) findViewById(R.id.linearLayout1); 
    container2 = (LinearLayout) findViewById(R.id.linearLayout2); 
    image = (ImageView) findViewById(R.id.imageView1); 
    image1 = (ImageView) findViewById(R.id.imageView2); 
    image2 = (ImageView) findViewById(R.id.imageView3); 
    tv = (TextView) findViewById(R.id.text_tech_des); 

    viewTree.getViewTreeObserver().addOnGlobalLayoutListener(//to check if the layout has been placed in activity 
      new OnGlobalLayoutListener() { 
       public void onGlobalLayout() { 
        if (Build.VERSION.SDK_INT < 16) { 
         viewTree.getViewTreeObserver().removeGlobalOnLayoutListener(this);} 
        else{ 
         viewTree.getViewTreeObserver() 
         .removeOnGlobalLayoutListener(this); 
        } 

        anim = ObjectAnimator.ofFloat(image, "y", 0f, 
          image.getTop()); 

        anim.addListener(new AnimatorListener() { 

         @Override 
         public void onAnimationStart(Animator arg0) { 
          // TODO Auto-generated method stub 
          ObjectAnimator.ofFloat(tv, "alpha", 1, 0, 1) 
            .setDuration(duration).start();//line no 82 
          ObjectAnimator.ofFloat(container1, "x", 0f, 
            container1.getLeft()).setDuration(1000).start(); 
          ObjectAnimator.ofFloat(container2, "x", 0f, 
            container2.getLeft()).setDuration(1000).start(); 
         } 

         @Override 
         public void onAnimationRepeat(Animator arg0) { 
          // TODO Auto-generated method stub 

         } 

         @Override 
         public void onAnimationEnd(Animator arg0) { 
          // TODO Auto-generated method stub 
         } 

         @Override 
         public void onAnimationCancel(Animator arg0) { 
          // TODO Auto-generated method stub 

         } 
        }); 
        anim.setDuration(duration).start();//line no 106 
       } 
      }); 

} 
} 

這是我的堆棧跟蹤:

10-26 19:23:15.203: E/AndroidRuntime(21541): FATAL EXCEPTION: main 
10-26 19:23:15.203: E/AndroidRuntime(21541): java.lang.NullPointerException 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.PropertyValuesHolder.setupSetterAndGetter(PropertyValuesHolder.java:523) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ObjectAnimator.initAnimation(ObjectAnimator.java:410) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ValueAnimator.setCurrentPlayTime(ValueAnimator.java:538) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ValueAnimator.start(ValueAnimator.java:928) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ValueAnimator.start(ValueAnimator.java:951) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ObjectAnimator.start(ObjectAnimator.java:385) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.vishalaksh.technex.ActivityActualMain$2$1.onAnimationStart(ActivityActualMain.java:82) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ValueAnimator.start(ValueAnimator.java:937) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ValueAnimator.start(ValueAnimator.java:951) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.nineoldandroids.animation.ObjectAnimator.start(ObjectAnimator.java:385) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.vishalaksh.technex.ActivityActualMain$2.onGlobalLayout(ActivityActualMain.java:106) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:808) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1768) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.Choreographer.doCallbacks(Choreographer.java:562) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.Choreographer.doFrame(Choreographer.java:532) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.os.Handler.handleCallback(Handler.java:730) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.os.Handler.dispatchMessage(Handler.java:92) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.os.Looper.loop(Looper.java:137) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at android.app.ActivityThread.main(ActivityThread.java:5103) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at java.lang.reflect.Method.invokeNative(Native Method) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at java.lang.reflect.Method.invoke(Method.java:525) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
10-26 19:23:15.203: E/AndroidRuntime(21541): at dalvik.system.NativeStart.main(Native Method) 

回答

1

我的設備API < 10,這給了相同的堆棧跟蹤有一個問題與此庫。鑑於我使用NineOldAndroids的源代碼,我決定調查庫內的問題。

經過一些測試,我注意到這個錯誤發生是因爲lib試圖調用視圖中不存在的某些方法(因爲它的舊API級別)。多搜索一下,我發現AnimatorProxy類有一個名爲「wrap」的靜態方法。此方法用於在較舊的Android版本中封裝View對象,模擬某些動畫方法的存在,例如setScaleX/Y,setTransalationX/Y。

要解決這個問題,我不得不打開ObjectAnimator類和搜索該行的所有出現(在我的庫中的代碼,我發現出現4次):

mTarget = target; 

I類創建了以下方法中:

private void setTarget(Object obj) { 
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB && obj instanceof View) { 
     mTarget = AnimatorProxy.wrap((View) obj); 
    } else { 
     mTarget = obj; 
    } 
} 

並替換上面的行:

setTarget(target); 

不知道它是否能解決你的問題,因爲你說它發生在API 10+(我的對面),但它是一個很好的開始。

+0

我有像你這樣的改變,Force close已經解決了。但是,在API8中,動畫不會像以前一樣播放。 –