如何将2D原始图形绘制到作为布局子成员的SurfaceView?

时间:2016-06-16 02:48:20

标签: android surfaceview

我只是学习Android和Java。我熟悉其他语言的图形和编程。

我有一个简单的布局,其中有一些按钮,文本视图和SurfaceView都在RelativeLayout中,如下所示:

  <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Quit"
        android:id="@+id/buttonShutdown"
        android:layout_below="@+id/textView2"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:onClick="shutdown"/>
    <SurfaceView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/surfaceView"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_below="@+id/buttonShutdown"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>

然后我有一个简单的MainActivity.java,它是这样的:

public class MainActivity extends AppCompatActivity
{
    SurfaceView surfaceView;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        holder = surfaceView.getHolder();
        holder.getSurface();
     }

    protected void shutdown(View view)
    {
        System.exit(0);
    }

}

显然我的代码还有一些,因为我有几个按钮和几个文本视图,但关键是我有一个包含几个小部件的布局,而SurfaceView只是其中之一。

我已经看过一些绘制到表面视图的例子,但它们似乎都接管整个屏幕和东西。

如何在不删除其余代码或布局小部件的情况下,简单地将2D线条和内容绘制到SurfaceView中?

我已经在这方面工作了好几天,它从来没有在任何其他语言/框架上花费太多努力来简单地绘制一些2D线!

对于使用现有布局工作的任何工作示例,我将非常感激。

更新:

为了澄清,我遇到的问题是如何获取surfaceView上的句柄以获得处理程序以便在其上获得画布。一旦我得到一个画布界面,我就可以锁定,绘制和解锁。但我无法弄清楚如何将Canvas附加到surfaceView。

更新:

我认为我现在有一个表面视图的持有者,但我如何获得它的画布?

非常感谢,

杰西

1 个答案:

答案 0 :(得分:0)

好吧,经过多次拔毛,我得到了它。

现在请给大家一个注意事项:这是一个非常简单的教育演示,用于在Surface View中在屏幕上绘制线条的最小代码。我也知道holder.getSurface();需要一些时间来活跃,因此绘画不会立即发生。这就是它在onClick中的原因。我也知道SurfaceView渲染应该从它自己的线程完成,并且应该设置3个回调。

这只是一个简单的样本,所以请不要因为没有写出理想的完全成熟的应用而激怒我!谢谢你。

我的MainActivity.java:

package com.gladeworks.gwscope ;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity
{
    TextView textView = null;
    SurfaceView surfaceView;
    SurfaceHolder holder;
    Canvas canvas;
    Paint paint;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.textView);
        textView.setText("Press the Draw button!");
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        holder = surfaceView.getHolder();
        holder.getSurface();
        paint = new Paint();

        final Button buttonDraw = (Button) findViewById(R.id.buttonDraw);
        buttonDraw.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View view)
            {
                draw(view);
            }
        });
    }


    protected void draw(View view)  //This gets called when the Draw button is clicked.
    {
        paint.setColor(Color.GREEN);
        paint.setStrokeWidth(5);

        canvas = holder.lockCanvas();
        if (canvas == null) {
            textView.setText("Canvas is still null");
        } else {
            canvas.drawRGB(32, 32, 255);    //Clear the canvas to light blue
            canvas.drawLine(0,0,1000,1000,paint);//Draw a line from top left corner down and right.
            holder.unlockCanvasAndPost(canvas);
            textView.setText("Done drawing!");
        }


    }

}

这是我的activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<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="com.gladeworks.gwscope.MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Uninitialized"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignBottom="@+id/buttonExit"
        android:layout_toLeftOf="@+id/buttonExit"
        android:layout_toStartOf="@+id/buttonExit"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Quit"
        android:id="@+id/buttonExit"
        android:layout_alignTop="@+id/buttonDraw"
        android:layout_toLeftOf="@+id/buttonDraw"
        android:layout_toStartOf="@+id/buttonDraw"/>


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Draw"
        android:id="@+id/buttonDraw"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"/>

    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/buttonExit"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"/>

</RelativeLayout>

需要改进的地方: 线条绘制代码应该在它自己的线程中,因此它不会阻止用户界面线程。 按钮和内容的标签应该在资源文件中定义,以便于翻译工作。 画布和SurfaceView shuold可以设置回调来处理创建,更改和销毁。

但这应该为初学者提供了一条清晰的途径,以便了解将线图形绘制到SurfaceView所需的步骤顺序。