たぼさんの部屋

いちょぼとのんびり

L001) RelativeLayout でsurfaceView をレイアウトして円を移動描画

目的

ViewGroupの部品を指定位置に配置する
RelativeLaoutをベースに使う。SurfaceViewも指定位置に配置できる。

point

MarginLayoutParams

width,height,leftMargin,topMarginを指定できる

MarginLayoutParams params = (MarginLayoutParams)View.getLayoutParams();
//set
View.setLayoutPrams(params);

Holderのサイズ指定

holder.setFixedSize()を使う必要なし。
インスタンス生成時のマージン指定でwidth,heightされている。

this.getWidth()
this.getHeight()

で取得。

SurfaceViewの背景色指定はcanvas.drawColor(Color);

setBackgroundColorでの設定はしないで、Run()内でcanvas.drawColorメソッドで色塗りつぶし。
(setBackgroundColorメソッドでは、canvasが見えなくなってしまう)

Run内ではインスタンス生成しない

Paint p = new Paint()のようにインスタンス生成は事前に行っておく。
エミュレータで動作が止まってしまった)

動作

f:id:donsuka_kk:20121115232558p:plain

Main.java

package com.example.l001_relativelayout;

import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.Window;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class Main extends Activity {
	Context context;
	RelativeLayout base;
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
	    super.onCreate(savedInstanceState);
	    
	    requestWindowFeature(Window.FEATURE_NO_TITLE);
	    
	    context = getApplicationContext();
	    
	    base = new RelativeLayout(context);
	    setContentView(base);
	    
	    //TextView
	    TextView tv = new TextView(context);
	    base.addView(tv);
	    tv.setBackgroundColor(Color.RED);
	    tv.setText("hogehoge");
	    tv.setTextColor(Color.BLUE);
	    tv.setPadding(10, 10, 0, 0);
	    
	    MarginLayoutParams params = (MarginLayoutParams)tv.getLayoutParams();
	    params.width = 200;
	    params.height = 100;
	    params.leftMargin = 100;
	    params.topMargin = 500;
	    tv.setLayoutParams(params);
	    
	    
	    //SurfaceView
	    MySurfaceView surface = new MySurfaceView(context);
	    base.addView(surface);
//	    surface.setBackgroundColor(Color.GREEN);	//これも指定すると描画内容見えない
	    MarginLayoutParams surfaceParams = (MarginLayoutParams)surface.getLayoutParams();
	    surfaceParams.width = 200;
	    surfaceParams.height = 100;
	    surfaceParams.topMargin = 50;
	    surfaceParams.leftMargin = 50;
	    surface.setLayoutParams(surfaceParams);
	    
	    //SurfaceView
	    MySurfaceView surface_2 = new MySurfaceView(context);
	    base.addView(surface_2);
//	    surface.setBackgroundColor(Color.GREEN);	//これも指定すると描画内容見えない
	    MarginLayoutParams surfaceParams_2 = (MarginLayoutParams)surface_2.getLayoutParams();
	    surfaceParams_2.width = 100;
	    surfaceParams_2.height = 200;
	    surfaceParams_2.topMargin = 100;
	    surfaceParams_2.leftMargin = 200;
	    surface_2.setLayoutParams(surfaceParams_2);
	}
}

MySurfaceView.java

package com.example.l001_relativelayout;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView 
implements Runnable , SurfaceHolder.Callback{
	SurfaceHolder holder;
	Thread thread;
	private int 
	px = 10,		//X座標
	py = 10,		//Y座標
	r = 10,		//半径
	vx = 3,		//X速度
	vy = 3;		//Y速度
	public MySurfaceView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
		
//		setBackgroundColor(Color.GRAY);
		//XXX ここで背景色を指定すると、描画が見えない(下にいってる?)
		
		//サーフェイスホルダーの生成
		holder = this.getHolder();	//extends SurfaceViewだから取得できる
		holder.addCallback(this);
		//holder.setFixedSize(300	, 300);
	}

	@SuppressWarnings("static-access")
	@Override
	public void run() {
		// TODO Auto-generated method stub
		Canvas canvas;
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		paint.setColor(Color.YELLOW);
		while(thread != null){
			//ダブルバッファリング
			canvas = holder.lockCanvas();
			canvas.drawColor(Color.GRAY);	//ここで背景書く
			canvas.drawCircle(px,py,r,paint);
			holder.unlockCanvasAndPost(canvas);
			
			//ぶつかり判定と移動
			//width,heightも取得できる
			//getWidth,getHeightはthisで使う。(SurfaceView)
			if(px-r < 0 || this.getWidth() < px+r){
				vx = -vx;
			}
			if(py-r < 0 || this.getHeight() < py+r){
				vy = -vy;
			}
			px += vx;
			py += vy;
			
			try {
				thread.sleep(50);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		thread = new Thread(this);
		thread.start();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		thread = null;
	}

}