安卓上如何在画布上进行动态2D绘制

3
我正在尝试理解如何在Android上动态生成2D图形。我在网上找不到任何人做这个的例子。
我的示例随机绘制1000条随机颜色的线条。我想看到所有的线条被绘制,但是在setContentView()调用之前我看不到任何东西(此时所有的线条已经被绘制)。
我尝试了许多排列组合,包括将setContentView()移到draw()调用之前,并在for循环中添加ourView.invalidate(),但在每种情况下屏幕都保持白色,直到所有线条都被绘制。
如果有人能指出一个这样工作的例子,我会很高兴去研究它并自己添加正确的答案。
package com.example.graphicsdemo;
+imports

public class MainActivity extends Activity {
    ImageView ourView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        draw();
        setContentView(ourView);
    }
    public void draw() {
        Bitmap blankBitmap = Bitmap.createBitmap(600,600,Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(blankBitmap);
        ourView = new ImageView(this);
        ourView.setImageBitmap(blankBitmap);
        Paint paint = new Paint();
        Random random = new Random();

        for(int i = 0 ; i < 1000 ; i++) {
            paint.setColor(Color.argb(255, random.nextInt(255), random.nextInt(255), random.nextInt(255)));
            canvas.drawLine(random.nextInt(600), random.nextInt(600), random.nextInt(600), random.nextInt(600), paint);
        }
    }
}
1个回答

4
我希望这个例子能有所帮助: 首先,创建你自己的视图,并将其称为“DynamicView”:
import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class DynamicView extends View {
    int i = 0;

    public DynamicView(Context context) {
        super(context);


    }

    @Override
    protected void onDraw(Canvas canvas) {

        Paint paint = new Paint();
        Random random = new Random();
        paint.setColor(Color.argb(255, random.nextInt(255),
                random.nextInt(255), random.nextInt(255)));
        canvas.drawLine(random.nextInt(600), random.nextInt(600),
                random.nextInt(600), random.nextInt(600), paint);

        if (i < 1000) {
            i++;
            invalidate();
        }
    }

}

这个视图每次绘制后将会在1000毫秒后失效。

现在,这是您的主活动的onCreate方法:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        DynamicView myView = new DynamicView(this);
        setContentView(myView);
    }

就像这样简单。

回答你的问题,这是一段更好的代码,更复杂但仍然易于理解。我们所要做的就是在位图上绘制线条,然后将该位图绘制到视图上,因此位图不会更改,并且将拥有所有之前绘制的线条并继续在其上绘制。

现在这里是更新后的代码:

DynamicView

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

public class DynamicView extends View {
    int i = 0;
    Bitmap frame ;
    Canvas frameDrawer;
    Rect bounds;
    Paint paint ;
    Random random ;
    int width , height;

    public DynamicView(Context context ,int width ,int height) {
        super(context);

        this.width = width;
        this.height = height;

        frame = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
        frameDrawer = new Canvas(frame);
        bounds = new Rect(0 , 0, width,height);
        //this initialization will make the frameDrawer draw on the frame bitmap

        //always avoid allocating new objects in the draw method to optimize the performance 
        paint = new Paint();
        random = new Random();
    }

    @Override
    protected void onDraw(Canvas canvas) {


        paint.setColor(Color.argb(255, random.nextInt(255),
                random.nextInt(255), random.nextInt(255)));
        //instead of drawing on the view canvas draw on the frame bitmap
        frameDrawer.drawLine(random.nextInt(width), random.nextInt(height),
                random.nextInt(width), random.nextInt(height), paint);
        // and then draw the bitmap on the view canvas
        canvas.drawBitmap(frame, null, bounds , null);

        if (i < 1000) {
            i++;
            invalidate();
        }
    }

}

现在 MainActivity 中的新功能是我们可以控制视图绘制边界,但仍无法控制占据整个屏幕空间的视图边界(如果您想调整视图边界,请实现 onLayout 方法并输入您的值)。

MainActivity

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        DynamicView myView = new DynamicView(this,320,480);
        setContentView(myView);
    }
}

这是一个很棒的答案,实际上帮助我理解了onDraw()/invalidate()范例。谢谢你。我发现我在问题中漏掉了一些东西 - 我想要新行被添加到视图中,以便显示所有绘制的线条的总和。当我运行你的例子时,结果是1000条独立的线条,每个都绘制在一个纯白色的背景上。 - dkimble
非常感谢这个。它运行得很好。现在去学习更多关于它为什么工作(即位图)的知识。 - dkimble

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接