因项目需要,在Android中实现了一个动画,当在Activity中点击特定按钮时,会在屏幕上添加一个ImageView,并按照指定的起点、终点,沿着特定的轨迹运动(例如直线)。

实现方法

实现思路是在Activity的DecorView中添加一个FrameLayout,然后在FrameLayout中添加ImageView,可通过Margin参数指定ImageView的起始位置。然后设置ImageView的动画,使其能运动到终点。当动画结束后,移除FrameLayout。

核心代码如下。项目GitHub链接 https://github.com/jzj1993/AnimationCrash

  1. public static boolean startAnim(Activity activity, int fromX, int toX, int fromY, int toY) {
  2. try {
  3. final ImageView img = new ImageView(activity);
  4. img.setImageResource(R.mipmap.ic_launcher);
  5. final FrameLayout tempLayout = new FrameLayout(activity);
  6. final FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
  7. FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
  8. lp.setMargins(fromX, fromY, 0, 0);
  9. tempLayout.addView(img, lp);
  10. final ViewGroup container = (ViewGroup) activity.getWindow().getDecorView();
  11. container.addView(tempLayout, new ViewGroup.LayoutParams(
  12. ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
  13. final Animation anim = new TranslateAnimation(0, toX - fromX, 0, toY - fromY);
  14. anim.setDuration(500);
  15. anim.setAnimationListener(new Animation.AnimationListener() {
  16. @Override
  17. public void onAnimationStart(Animation animation) {
  18. }
  19. @Override
  20. public void onAnimationEnd(Animation animation) {
  21. container.removeView(tempLayout);
  22. }
  23. @Override
  24. public void onAnimationRepeat(Animation animation) {
  25. }
  26. });
  27. img.startAnimation(anim);
  28. } catch (Exception e) {
  29. e.printStackTrace();
  30. }
  31. return true;
  32. }

错误描述

在大部分安卓手机上运行正常,但是在部分Android 4.0.x系统中(例如Nexus S Android 4.0.3模拟器),如果连续同时执行多个动画,可能会出现NullPointerException,如下:

  1. com.jzj1993.anim E/AndroidRuntime﹕ FATAL EXCEPTION: main
  2. java.lang.NullPointerException
  3. at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2488)
  4. at android.view.View.draw(View.java:10981)
  5. at android.widget.FrameLayout.draw(FrameLayout.java:450)
  6. at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2126)
  7.             at android.view.ViewRootImpl.draw(ViewRootImpl.java:2026)
  8.             at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1634)
  9.             at android.view.ViewRootImpl.handleMessage(ViewRootImpl.java:2442)
  10.             at android.os.Handler.dispatchMessage(Handler.java:99)
  11.             at android.os.Looper.loop(Looper.java:137)
  12.             at android.app.ActivityThread.main(ActivityThread.java:4424)
  13.             at java.lang.reflect.Method.invokeNative(Native Method)
  14.             at java.lang.reflect.Method.invoke(Method.java:511)
  15.             at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
  16. at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
  17. at dalvik.system.NativeStart.main(Native Method)

解决方法

将以下代码

  1. @Override
  2. public void onAnimationEnd(Animation animation) {
  3. container.removeView(tempLayout);
  4. }

改为:

  1. @Override
  2. public void onAnimationEnd(Animation animation) {
  3. container.post(new Runnable() {
  4. @Override
  5. public void run() {
  6. container.removeView(tempLayout);
  7. }
  8. });
  9. }

原因分析

以下是官方给出的ViewGroup.removeView方法的JavaDoc注释:

  1. public void removeView (View view)
  2. Added in API level 1
  3. Note: do not invoke this method from draw(android.graphics.Canvas), onDraw(android.graphics.Canvas), dispatchDraw(android.graphics.Canvas) or any related method.

猜测在同时执行多个动画时,前一个动画的onAnimationEnd被回调时,后一个动画正在执行,因此DecorView的onDraw方法在执行,可能会导致DecorView.onDraw执行时,onAnimationEnd回调中的DecorView.removeView方法被调用,从而导致错误。没有具体深入的去分析源码,但是经过验证问题确实解决了。

本文由jzj1993原创,转载请注明来源:http://www.paincker.com/android-animation-crash

Android Animation实现元素在屏幕上按照指定轨迹运动,以及出现NullPointerException的解决方案相关推荐

  1. android滑屏轨迹运动,Android Animation实现元素在屏幕上按照指定轨迹运动,以及出现NullPointerException的解决方案...

    因项目需要,在Android中实现了一个动画,当在Activity中点击特定按钮时,会在屏幕上添加一个ImageView,并按照指定的起点.终点,沿着特定的轨迹运动(例如直线). 实现方法 实现思路是 ...

  2. python获取网页元素坐标_html网页元素在屏幕上的坐标获取

    今天在用python调用IE获取html网页元素在屏幕上的坐标,当然为了截图啦,(*^__^*) 嘻嘻-- xtop=ie.document.forms[i].elements[j].getBound ...

  3. Linux 命令之 tail -- 在屏幕上显示指定文件的末尾若干行/显示文件尾部内容/查看文件尾部内容

    文章目录 一.命令介绍 二.常用选项 三.参考示例 (一)显示文件 file 的最后 10 行 (二)显示文件 file 的内容,从第 20 行至文件末尾 (三)显示文件file的最后10个字符 (四 ...

  4. android广播内容显示在屏幕上,在Android本机来电屏幕上弹出窗口,例如真正的来电者Android应用...

    我也在努力(在这里理解你可能是错误的).您想要实现的是在Android 4.2(Jelly Bean)中显示该活动.我只是延迟显示活动.我在其他类中使用过PhoneStateListener.我可以在 ...

  5. thinkpad卡在logo界面_由于win7系统启动卡在Thinkpad LOGO屏幕上而导致无法进入系统的三种解决方案...

    最近联想平板卡在主界面,一个Win7 pure版本系统的用户报告说,在打开计算机电源时,发现它卡在了Thinkpad引导LOGO屏幕上,并且无法正常进入系统桌面. win7系统卡在徽标界面上的原因有很 ...

  6. android广播内容显示在屏幕上,如何将手机屏幕投影到计算机显示器上?

    该屏幕广播应用程序摆脱了电缆的束缚,可以将手机的内容投影到电视中的空白空间,以便您可以在电视侧更好地欣赏自己喜欢的视频和图片. 一方面,它用于工作,另一方面,用于家庭生活和娱乐. 实际上,有时无法很好 ...

  7. android中可以有两个焦点吗,android – 如何通过焦点在屏幕上调整两个片段的大小?...

    我有三个片段,前两个填充80%的屏幕,最后一个填充其余的片段(这个片段永远不会改变大小).我希望,在用户(焦点)输入片段后,调整片段的大小,使其填满屏幕的70%(将10%留给另一个).像这样: 可以通 ...

  8. Android:设计一个在屏幕上移动的小球程序

    目录 1.要求 2.结构 3.设计步骤 4.实现效果 1.要求 设计一个自定义组件继承于Android.view.View的图形绘制类TestView,在该视图组件中绘制一个小球:再设计一个实现监听触 ...

  9. Android 使用 ADB 命令录制屏幕上的视频

    ADB 录制使用使用到的 screenrecord  顺便提一下截图使用的是screencap 关于截图可以看这篇文章,点击可以查看 首先需要我们确保adb devices 输入有显示内容 然后在终端 ...

最新文章

  1. 关于Silverlight安装问题之二
  2. curl命令的超时时间
  3. 服务器于本地间进行复制粘贴
  4. mysql自动dump脚本_MySQL--简单mysqldump脚本
  5. 【Task5(2天)】模型调参
  6. linux显示mem进行排序,Linux查看系统负载(CPU和MEM考虑)
  7. Hashtable、HashMap、TreeMap总结
  8. 苹果CMSV10绿色毛毛虫主题模板
  9. freemaker转word xml注意事项
  10. Golang 删除切片指定元素
  11. Python yaml模块
  12. SSH dao层异常 org.hibernate.HibernateException: No Session found for current thread
  13. iOS手势的传递问题
  14. python入门到精通 _6文件读写
  15. execute immediate
  16. ETR290规范的理解
  17. Python小白逆袭大神-结营心得-alading
  18. 【多线程基础】 保证线程安全的总结
  19. TextField及富文本框的用法
  20. (java版)删除重复值阿伟学长在开发一款游戏, 他希望玩家已经获得的道具会降低爆率, 避免玩家获得太多重复的道具但玩家背包中道具是乱序且不确定的, 为了减小判断的运算量, 需要先对数据进行去重.

热门文章

  1. 使用windows server backup备份还原hyper-v 3.0虚拟机
  2. shell编程中特殊字符的问题总结
  3. java hasmoreelements_Java IOException.hasMoreElements方法代码示例
  4. Java31 gt gt gt 2_Java Template.binding方法代碼示例
  5. honeywell新风系统控制面板说明_新风系统——不开窗也能清新呼吸
  6. Kate and imperfection CodeForces - 1333F(思维+数学)
  7. [蓝桥杯][算法提高VIP]数的划分(记忆化搜索)
  8. 173. 二叉搜索树迭代器(二叉搜索树+栈)
  9. Interesting Array CodeForces - 483D(思维+线段树)
  10. Ciel and Robot CodeForces - 322C