【问题标题】:Making multiple images animate sequentially使多个图像按顺序制作动画
【发布时间】:2015-02-09 05:59:54
【问题描述】:

这里完全是菜鸟,所以请原谅我的无知。我找到了一些动画 ImageView 的代码:

public void startAnimatedBackground(Integer num) {

    ImageSwitcher imageSwitcher = null;
    switch (num) {
        case 0:
            imageSwitcher = img_0;
            break;
        case 1:
            imageSwitcher = img_1;
            break;
        case 2:
            imageSwitcher = img_2;
            break;
        case 3:
            imageSwitcher = img_3;
            break;
        default:
            break;
    }
    imageSwitcher.setInAnimation(aniIn);
    imageSwitcher.setOutAnimation(aniOut);
    imageSwitcher.setFactory(this);
    imageSwitcher.setImageResource(images[index]);

    final Handler handler = new Handler();
    final ImageSwitcher finalImageSwitcher = imageSwitcher;
    Runnable runnable = new Runnable() {

        @Override
        public void run() {
            if (isRunning) {
                index++;
                index = index % images.length;
                finalImageSwitcher.setImageResource(images[index]);
                handler.postDelayed(this, interval);
            }
        }
    };
    handler.postDelayed(runnable, interval);

}

public View makeView() {
    ImageView imageView = new ImageView(this);
    imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
    imageView.setLayoutParams(new ImageSwitcher.LayoutParams(
            TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.MATCH_PARENT));
    return imageView;
}

@Override
public void finish() {
    isRunning = false;
    super.finish();
}}

我正在 onCreate() 上创建一些需要的代码:

    private int index = 0;
private boolean isRunning = true;
Animation aniIn;
Animation aniOut;
ImageSwitcher img_0,img_1,img_2,img_3;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.user_walk_in_progress);
    aniIn = AnimationUtils.loadAnimation(this,
            android.R.anim.fade_in);
    aniOut = AnimationUtils.loadAnimation(this,
            android.R.anim.fade_out);

    aniIn.setDuration(500);
    aniOut.setDuration(500);
    img_0 = (ImageSwitcher) findViewById(R.id.switcher_accept);
    img_1 = (ImageSwitcher) findViewById(R.id.switcher_on_way);
    img_2 = (ImageSwitcher) findViewById(R.id.switcher_in_progress);
    img_3 = (ImageSwitcher) findViewById(R.id.switcher_finished);
    startAnimatedBackground(0);
}

现在第一个工作正常。现在在一个 Activity 中,我试图切换它以使第二张图像开始动画:

编辑:这个新的“活动”不是膨胀视图。新活动是一个 GCM Intent 服务,它只是监听通知并更新我的通知信息。当我收到此通知时,我想获取当前已在用户屏幕上显示的视图并更新动画以将其切换到第二张图像。

            WalkInProgress walk = new WalkInProgress();
        walk.startAnimatedBackground(1);

这会导致错误:

02-01 16:03:04.766 23805-24580/ly.leash.Leashly I/System.out﹕null 02-01 16:03:04.778 23805-24580/ly.leash.Leashly E/AndroidRuntime:致命异常:IntentService [GcmIntentService] 进程:ly.leash.Leashly,PID:23805 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“void android.widget.ImageSwitcher.setInAnimation(android.view.animation.Animation)” 在 ly.leash.Leashly.WalkInProgress.startAnimatedBackground(WalkInProgress.java:179) 在 ly.leash.Leashly.GcmIntentService.sendNotification(GcmIntentService.java:96) 在 ly.leash.Leashly.GcmIntentService.onHandleIntent(GcmIntentService.java:72) 在 android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:135) 在 android.os.HandlerThread.run(HandlerThread.java:61)

所以无论出于何种原因,动画都会返回 null。

我尝试在 startAnimatedBackground 函数而不是 onCreate 中声明它,但这也会导致错误:

02-01 16:15:10.488 25553-25930/ly.leash.Leashly E/AndroidRuntime: 致命异常:IntentService[GcmIntentService] 进程:ly.leash.Leashly,PID:25553 java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“android.content.res.Resources android.content.Context.getResources()” 在 android.content.ContextWrapper.getResources(ContextWrapper.java:85) 在 android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:74) 在 android.view.animation.AnimationUtils.loadAnimation(AnimationUtils.java:73) 在 ly.leash.Leashly.WalkInProgress.startAnimatedBackground(WalkInProgress.java:152) 在 ly.leash.Leashly.GcmIntentService.sendNotification(GcmIntentService.java:96) 在 ly.leash.Leashly.GcmIntentService.onHandleIntent(GcmIntentService.java:72) 在 android.app.IntentService$ServiceHandler.handleMessage(IntentService.java:65) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:135) 在 android.os.HandlerThread.run(HandlerThread.java:61)

错误在这一行:

        aniIn = AnimationUtils.loadAnimation(this,
            android.R.anim.fade_in);

【问题讨论】:

  • Now in a different part of the app 是什么意思?不同的活动?
  • 是的,不同的活动。对不起
  • 我猜img_1 不在这个新活动的布局文件中。我说的对吗?
  • 不,它在原始活动的布局中

标签: android animation


【解决方案1】:

空指针的原因是您尝试访问的ImageSwitcher 处于不同的活动中。您必须使用 img_1 = (ImageSwitcher) findViewById(R.id.switcher_on_way); 在这个新活动中再次实例化它(假设 ID 为 switcher_on_wayImageSwitcher 小部件在新活动的 XML 布局文件中)。

更新

为了从 GCM Intent 服务向您当前运行的 Activity 发送消息,您需要向该 Activity 发送广播。

确认用户当前正在查看您的活动后,创建Intent 并向活动发送广播:

/* create intent */
Intent intent = new Intent("my_animation");
intent.putExtra("message", message); <-- replace this with what you
                                         want to broadcast to your
                                         activity (which would be an
                                         integer specifying the new 
                                         ImageSwitcher)

/* send broadcast */
this.sendBroadcast(intent);

在您的活动中,创建一个将处理广播意图的BroadcastReceiver

/* this handler will process the broadcast intent */
private BroadcastReceiver messageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        // Extract data included in the Intent
        String message = intent.getStringExtra("message");

        // you could start your animation here 
    }
};

onResume 中注册BroadcastReceiver 并在onPause 中取消注册。

@Override
protected void onResume() {
    super.onResume();
    this.registerReceiver(messageReceiver, new IntentFilter("my_animation"));
}

@Override
protected void onPause() {
    super.onPause();
    this.unregisterReceiver(messageReceiver);
}

我希望这会有所帮助。

【讨论】:

  • 抱歉刚刚出差回来!谢谢您的回答,您是说 switcher_on_way 必须在新活动中?检查我上面的编辑。调用代码为第二张图像设置动画的活动实际上并不是当前正在查看的活动,它只是一个 GCM 服务,它看到我们有更新的 GCM 消息并尝试为已经显示的活动更新图像以上
  • 嘿,谢谢。我已经完全按照您在上面所做的那样做了,并且在我的原始活动中我没有使用 onReceive 函数。我还尝试在 Intent() 中添加要发送到的类的详细信息,但这仍然没有改变任何东西。我错过了什么?我不知道广播接收器,这些很棒!我将阅读并可能能够回答我自己的问题
  • @user1610719 我不确定为什么它不起作用,但我注意到我省略了意图操作(在创建IntentIntentFilter 时)。我已经添加了它。如果它不能解决您的问题,我希望您能尽快找到解决方案。
猜你喜欢
  • 2010-11-16
  • 1970-01-01
  • 2018-07-31
  • 1970-01-01
  • 2013-08-27
  • 1970-01-01
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
相关资源
最近更新 更多