I am using NineOldAndroid
library to perform animations. The animations work fine for API<=10. But for API>10 the app force closes. This is my code:
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
}
});
}
}
This is my stack trace:
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)
I had an issue with this library on devices API < 10, which gave the same stacktrace. Given i was using the source code of NineOldAndroids i decided to investigate the problem inside the library.
After some tests i noticed that this error occurs because the lib tries to invoke some methods that doesn't exists on the view (since its an old API level). Searching a bit more i found the AnimatorProxy class which has a static method called "wrap". This method is used to encapsulate View objects in older Android versions emulating the presence of some animation methods as such setScaleX/Y, setTransalationX/Y.
To fix the problem i had to open the ObjectAnimator class and search for all occurrences of this line (In my library code i found 4 occurrences):
mTarget = target;
Inside that class i created the following method:
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;
}
}
And replaced the line above with:
setTarget(target);
Don't know if it can fix your problem since you said that it occurs on API 10+ (the opposite of mine) but its a good point to start.
来源:https://stackoverflow.com/questions/19607703/nineoldandroids-animation-not-working-on-api10