前回、お絵かきアプリの基礎を勉強したが、
1、pathを配列で保持しておく。
2、canvasのキャプチャをとって、次の線が描かれたらキャプチャと線を重ねる。
です。今回は2の方法で作成をします。と書きましたが、今回は1の方法でお絵かきアプリを作成したいと思います。
参考:Android で再開する Java プログラミング(10) – 手書きメモを作る
前回の方法だと、毎回キャプチャを作って一枚の画像にしていました。
今回は1つの線を線として残しておくので、戻るなどの機能を簡単につける事ができます。
では作成していきます。
最初にpathを中に保持をするListを用意します。
ArrayList<Path> draw_list = new ArrayList<Path>();
次に前回と同様、タッチのイベントに対してpathを作成しますが、今回は最初にpathを生成して、最後にpathを配列の中にいれます。
public boolean onTouchEvent(MotionEvent e){ //イベントのタイプごとに処理を設定 switch(e.getAction()){ case MotionEvent.ACTION_DOWN: //最初のポイント path = new Path(); posx = e.getX(); posy = e.getY(); path.moveTo(e.getX(), e.getY()); break; case MotionEvent.ACTION_MOVE: //途中のポイント posx += (e.getX()-posx)/1.4; posy += (e.getY()-posy)/1.4; path.lineTo(posx, posy); invalidate(); break; case MotionEvent.ACTION_UP: //最後のポイント path.lineTo(e.getX(), e.getY()); draw_list.add(path); invalidate(); break; default: break; } return true; }
次に描画ですが、draw_listの中身の配列から線を描きます。
また、作成中のpathについては配列に入っていない為、配列の外で別途に線を描きます。
public void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(6); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeJoin(Paint.Join.ROUND); for (int i = 0; i < draw_list.size(); i++) { Path pt = draw_list.get(i); canvas.drawPath(pt, paint); } //current if(path != null){ canvas.drawPath(path, paint); } }
以上で完成です。書いてる最中はpathのデータを気にする必要がありますが、通常は気にする必要はありませんので、戻るや進むなどは、Listをいじる事で簡単にできそうですね。
下記に使用ソースを置いておきます。
DrawMemo.java
package in.andante.drawmemo; import android.app.Activity; import android.os.Bundle; public class DrawMemo extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); penView penview = new penView(this); setContentView(penview); } }
penView.java
package in.andante.drawmemo; import java.util.ArrayList; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.view.MotionEvent; import android.view.View; public class penView extends View { ArrayList<Path> draw_list = new ArrayList<Path>(); private float posx = 0f; private float posy = 0f; private Path path = null; public penView(Context context) { super(context); } public void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.BLUE); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(6); paint.setStrokeCap(Paint.Cap.ROUND); paint.setStrokeJoin(Paint.Join.ROUND); for (int i = 0; i < draw_list.size(); i++) { Path pt = draw_list.get(i); canvas.drawPath(pt, paint); } //current if(path != null){ canvas.drawPath(path, paint); } } public boolean onTouchEvent(MotionEvent e){ switch(e.getAction()){ case MotionEvent.ACTION_DOWN: //最初のポイント path = new Path(); posx = e.getX(); posy = e.getY(); path.moveTo(e.getX(), e.getY()); break; case MotionEvent.ACTION_MOVE: //途中のポイント posx += (e.getX()-posx)/1.4; posy += (e.getY()-posy)/1.4; path.lineTo(posx, posy); invalidate(); break; case MotionEvent.ACTION_UP: //最後のポイント path.lineTo(e.getX(), e.getY()); draw_list.add(path); invalidate(); break; default: break; } return true; } }
以上です。