首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SurfaceView中两种动画的同时显示

SurfaceView中两种动画的同时显示
EN

Stack Overflow用户
提问于 2021-03-19 03:33:08
回答 2查看 81关注 0票数 3

我正试着同时展示两个动画。应用程序构建成功,但在模拟器中崩溃。

我在一个线程中创建了一个Anim类,它可以在while循环中处理动画。我认为我的抽签方法有问题,但我似乎想不出来。

我很感谢你在这方面的帮助,谢谢

错误日志

代码语言:javascript
复制
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.myproject/com.example.myproject.MainActivity}: java.lang.IllegalArgumentException: Cannot add a null child view to a ViewGroup

代码语言:javascript
复制
java.lang.ArrayIndexOutOfBoundsException: length=2; index=2
        at com.example.my_project.PlayActivity$surfaceView$Anim.run(PlayActivity.java:109)

代码

代码语言:javascript
复制
public class PlayActivity extends AppCompatActivity {
surfaceView view;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    view = new surfaceView(this);

    setContentView(view);



public class surfaceView extends SurfaceView {


    public surfaceView(Context context) {
        super(context);
        new Anim().start();
    }


    private class Anim extends Thread {
        int counter = 0;
        int counter2 = 0;



        @Override
        public void run() {
            long last_updated_time = 0;
            long delay = 250;
            int[] purple_bird = {
                    R.drawable.bird1,
                    R.drawable.bird2
            };
            int[] red_bird = {
                    R.drawable.red1,
                    R.drawable.red2,
                    R.drawable.red3,
                    R.drawable.red4
            };


            while (true) {
                boolean playing = true;
                if (playing) {

                    long current_time = System.currentTimeMillis();
                    if (current_time > last_updated_time + delay) {
                        if ((counter >= 2) && (counter2 >= 4)) {
                            counter = 0;
                            counter2 = 0;


                        }
                        draw(purple_bird[counter], red_bird[counter2]);

                        last_updated_time = current_time;
                        counter++;
                        counter2++;
                    }
                }
            }




        }

        private void draw(int red_bird, int purple_bird) {

            SurfaceHolder holder = getHolder();
            Canvas canvas = holder.lockCanvas();

            if (canvas != null) {
                canvas.drawColor(Color.WHITE);
                Paint paint = new Paint();

                Bitmap purpleBird = BitmapFactory.decodeResource(getContext().getResources(), purple_bird);
                Bitmap redBird = BitmapFactory.decodeResource(getContext().getResources(), red_bird);


                Bitmap resizedRedBird = Bitmap.createScaledBitmap(redBird, (int) (redBird.getWidth() * 0.4), (int) (redBird.getHeight() * 0.4), true);
                Bitmap resizedPurpleBird = Bitmap.createScaledBitmap(purpleBird, (int) (purpleBird.getWidth() * 0.2), (int) (purpleBird.getHeight() * 0.2), true);

                canvas.drawBitmap(resizedRedBird, 500, 500, paint);
                canvas.drawBitmap(resizedPurpleBird, 100, 100, paint);

                holder.unlockCanvasAndPost(canvas);




            }

        }
    }





}

}

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-03-19 05:47:50

因为访问SurfaceView (使用画布)是独占的,所以不能同时绘制它。

代码语言:javascript
复制
holder.lockCanvas();

(...) // the canvas is locked during this

holder.unlockCanvasAndPost(canvas);

因此,您可能的解决方案是在同一线程的同一绘制方法(锁和解锁之间)中操作和绘制红色鸟和蓝鸟。

编辑

对于另一个错误2:

代码语言:javascript
复制
if ((counter >= 2) && (counter2 >= 4)) {
    counter = 0;
    counter2 = 0;
}

这种情况是错误的。因为只有当计数器和counter2都超出时,它们才会被重置。它们应分开:

代码语言:javascript
复制
if (counter >= 2) {
    counter = 0;
}
if (counter2 >= 4) {
    counter2 = 0;
}
票数 1
EN

Stack Overflow用户

发布于 2021-03-19 09:01:45

在Surface上绘图通常一次只能从一个线程中完成。

如果您想要从不同的线程中绘制,那么您必须考虑到"lockCanvas()“需要在每次调用时上传所有Surface像素,但是您只是在绘制每个动画像素而不考虑另一个像素。在这种行为中,“第二”线程将用它自己的像素“覆盖”整个Surface像素,这就是为什么您会看到闪烁的效果。

我建议您使用一个通用的位图来绘制(它将是唯一调用“unlockCanvasAndPost()”的位图),或者只是将这两个线程合并在一起,并在那里处理两个动画。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66702172

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档