Android:带有asynctask的螺纹绘图

时间:2013-07-04 16:57:55

标签: android android-asynctask draw surfaceview

我正在尝试在asynctask中的SurfaceView上绘制分形,但我不确定如何正确执行它。我的想法是创建包含进度条的surfaceview(在主活动中),而单独的线程将计算将绘制哪些像素并将其存储在某种“缓冲区”上(我使用画布)。之后应该绘制surfaceview结果(这应该会破坏进度条的旋转轮)。

我写了这段代码:

MainActivity.java

public class MainActivity extends Activity {
private Complex constant;
private int bg_color, fg_color;
private static final int nMax = 30, rMax = 2;

private class JuliaThread extends AsyncTask<Complex, Void, Canvas> {
    private double re, im, w, h;
    private Complex sequence;
    private int i;
    private Canvas canv;
    private Paint p;
    private View m;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        m = (View) findViewById(R.id.sv);
        w = m.getWidth();
        h = m.getHeight();
        canv = new Canvas();
        p = new Paint();
    }
    @Override
    protected Canvas doInBackground(Complex... c) {
        for (double y=0; y<h; y++) {
            for (double x=0; x<w; x++) {
                re = (x/w)*3.0-1.5;
                im = -(y/h)*3.0-1.5;
                sequence = new Complex(re, im);
                for (i=1; i<=nMax; i++) {
                    sequence = sequence.square();
                    sequence.add(c[0]);
                    if (sequence.abs() > rMax) break;
                }
                if (i == nMax) p.setColor(fg_color);
                else p.setColor(bg_color);
                canv.drawLine((float)x, (float)y, (float)x, (float)y, p);
            }
        }
        return canv;
    }
    @Override
    protected void onPostExecute(Canvas result) {
        super.onPostExecute(result);
        m.draw(result);
    }
}


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    constant = new Complex(-0.391, -0.587);
    bg_color = Color.rgb(0, 0, 0);
    fg_color = Color.rgb(255, 255, 255);
    new JuliaThread().execute(constant);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
}

activity_main.xml中

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:id="@+id/mainview" >

    <SurfaceView
        android:id="@+id/sv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true" >

    </SurfaceView>

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/sv"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="138dp" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/progressBar1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="15dp"
        android:text="@string/loading"
        android:textAppearance="?android:attr/textAppearanceLarge" />
</RelativeLayout>

不幸的是,这种方法不起作用。你能解释一下,我做错了什么以及如何正确地做到这一点?

1 个答案:

答案 0 :(得分:0)

您首先需要从SurfaceHolder获取SurfaceView(通过实施SurfaceHolder.Callback)。然后做一些事情:

 final Canvas c = mSurfaceHolder.lockCanvas();

 //---draw stuff--

 mSurfaceHolder.unlockCanvasAndPost(c);