2016-06-16 6 views
0

私はAndroidとJavaを学んでいます。私は他の言語での一般的なグラフィックスやプログラミングに精通しています。レイアウトのサブメンバであるSurfaceViewに2D primtivesを描画するにはどうすればよいですか?

私はいくつかのボタン、テキストビュー、およびすべてのこのようなRelativeLayout内部SurfaceViewとシンプルなレイアウトがあります。

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); 
    } 

} 
:その後、私はこのような単純なMainActivity.javaを持って

<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"/> 

明らかに、私はカップルのボタンといくつかのtextviewsを持っているので、私のコードはもう少しですが、ポイントはいくつかのウィジェットのレイアウトがあり、SurfaceViewはそれらの1つだけです。

私は表面図に描画する例をいくつか見てきましたが、すべてが画面全体を占めているようです。

残りのコードウィジェットまたはレイアウトウィジェットを削除せずに、2Dラインと素材をそのままSurfaceViewに描画するにはどうすればよいですか?

私は数日間この作業をしてきましたが、他の言語やフレームワークでこれほど多くの努力を払ったことはありませんでした。

私の既存のレイアウトで動作する作業例の中で、最も感謝します。

UPDATE:

明確にするために、私はとのトラブルを抱えている問題は、その上にキャンバスを得るためにハンドラを取得するためにsurfaceViewのハンドルを取得する方法です。キャンバス・インターフェースを取得すると、ロック、描画、ロック解除ができます。しかし、私はcanvasをsurfaceViewにアタッチする方法を理解できません。

UPDATE:

私は今、表面ビューのためのホルダーを持っていると思うが、どのように私はそれのためにキャンバスを取得するのですか?

は、多くの髪が、私はそれが働いてしまった引っ張った後

ジェシー

+0

私はおそらくあなたがコントロールボタンを含むサイドパネルを作ろうとしていることを理解していて、残りの部分はカスタム図面に使用されていると私は間違っていますか? – Harshiv

+0

Harshiv、あなたは部分的に正しい - 私は、SurfaceViewの外側でコントロールボタンと情報テキストビューを持っていて、彼らはRelativeLayoutのSurfaceViewを持つすべての兄弟です。 SurfaceViewは残りの部分を占める可能性がありますが、それはポイントではありません。それは他のアイテムの兄弟ですが、別のスレッドから色付きの2D線を描きたいのですが、その点以外にもあります。ありがとう、Jesse –

+0

最初に気になることは、onTouch(Event.ACTION_MOVEなんかのような)メソッドのtouch座標をチェックして、もしそれらがsurfaceViewエリアにあるならば 'else '戻ります。 – Harshiv

答えて

0

オーケー、ありがとうございました。

ここであなたに注意してください。これは、表面ビューで画面に線を描くための最小限のコードの非常に簡単な教育デモであることを意図しています。私も知っている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は、作成、変更、および破棄を処理するコールバックを設定します。

しかし、これは、ライングラフィックスをSurfaceViewに描画するために必要な一連の手順を理解するための初心者に明確な道を提供するはずです。

+0

他の人のためのチュートリアルを作成する場合は、特に別のスレッドを追加する場合は、https://source.android.com/devices/graphics/architecture.html#activityを理解してください。 SurfaceViewは他のビューとは非常に異なっています。ほとんどの場合、カスタムビュー(http://developer.android.com/training/custom-views/index.html)を使用するほうがずっと簡単です。キャンバスでのレンダリングはハードウェアアクセラレーションが可能です。 – fadden

+0

おかげでファドデン - オシロスコープやゲームのような30/60fpsのリアルタイムレンダリング設定では、どのようなアプローチをお勧めしますか? SurfaceView以外のものはそれより優れていますか?ありがとう! Jesse –

+0

Canvasを使用する場合はカスタムビューを使用し、OpenGL ESを使用する場合はSurfaceViewを使用します。後者はかなり速くなる可能性がありますが、GLESは急速な学習曲線を持っています。グラフィックスエンジンではなくアプリを書くことに興味があるなら、オープンソースのグラフィックスエンジン、またはゲームエンジンの1つを使用することをお勧めします。 – fadden