ホームへ戻る

s1.2 Viewに手書き絵を描く


 手書きでお絵かきが出来るようにするための方法を説明します。

1. Viewの大きさでBitmapを作る。
2. それをキャンバスにセットする
3. 作ったBitmapをViewの面に設定する
4. タッチイベントを取得し、前に検出した点→今検出した点をdrawLineする
5. 再描画イベントをコールする →4へ

こうして4,5をひたすら繰り返すことで実現します。
ではこれを行うソースコードを見て下さい。

色を定義するクラスを新規作成し、先ほど作った自作クラスである PaintView の中身を変更します。


↓Def.java を新規作成

package net.dixq.painter;

import android.graphics.Color;

public class Def {
        public static final class color {
                public final static int red   = Color.argb(255, 240,  20,  20);
                public final static int green = Color.argb(255,  20, 240,  20);
                public final static int blue  = Color.argb(255,  20,  20, 240);
                public final static int erase = Color.argb(255, 255, 255, 255);
        }
}


↓PaintView.javaの変更内容

package net.dixq.painter;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;

public class PaintView extends ImageView {

        private Paint mPaint = new Paint();             //ペンの設定
        private int mPenColor = Def.color.red;  //ペンの現在の選択色
        private final int THICKNESS = 10;               //太さ
        private PointF mStartPt = new PointF(); //始点
        private PointF mEndPt   = new PointF(); //終点
        private Bitmap mBmp = null;                             //ViewにセットするBmp
        private Canvas mCanvas = null;                  //キャンバス

        public PaintView(Context context, AttributeSet attrs) {
                super(context, attrs);
                mPaint.setColor(mPenColor); // 色設定
                mPaint.setStrokeWidth(THICKNESS); // 太さ設定
                mPaint.setStrokeCap(Paint.Cap.ROUND); // 角を円く
        }

        @Override
        protected void onMeasure(int wSpec, int hSpec) {
                super.onMeasure(wSpec, hSpec);
                int w = MeasureSpec.getSize(wSpec);//幅を計算
                int h = MeasureSpec.getSize(hSpec);//高さを計算
                mBmp = Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888);//Bmpを作る
                mCanvas = new Canvas(mBmp);//キャンバスにセット
                mCanvas.drawColor(Color.WHITE);//白で塗りつぶし
                this.setImageBitmap(mBmp);//mBmpをImageViewの面に設定する
        }
        
        @Override
        public boolean onTouchEvent(MotionEvent e) { // タッチ時に呼ばれる
                switch (e.getAction()) {
                case MotionEvent.ACTION_DOWN: // 画面がタッチされたときの動作
                        mStartPt.set(e.getX()-1, e.getY()-1);// チョン押しでも描画されるように-1
                        DrawLine(e);
                        break;
                case MotionEvent.ACTION_MOVE: // タッチしたまま移動したときの動作
                        DrawLine(e);
                        break;
                case MotionEvent.ACTION_UP: // タッチが離されたときの動作
                        DrawLine(e);
                        break;
                } 
                return true;
        }

        //線を引く
        private void DrawLine( MotionEvent e ){
                mEndPt.set(e.getX(),e.getY());
                mCanvas.drawLine(mStartPt.x, mStartPt.y, mEndPt.x, mEndPt.y, mPaint);
                mStartPt.set( mEndPt );
                invalidate();   //再描画イベントを起こす
        }
        
}


まず、コンストラクタでは、ペンの設定を行っています。
色・太さ・角を円くするなどの設定です。

onMeasureは先ほど紹介した、必ず必要なメソッドで、Viewの大きさが引数に渡されてきます。
引数に渡されてきた値は、MeasureSpec.getSize メソッドで実際に使用出来る値に変換出来ます。
ここで、Viewの大きさが分かるので、Viewの面として設定するBitmapを作ります。

作ったビットマップは、塗りつぶしやdrawLineを行うために、Canvasクラスにセットしておきます。
drawColorで白で塗りつぶしたら、作ったビットマップをViewの面としてsetImageBitmapで登録します。

onTouchEventは別の章で説明した通りなので特に説明は要らないと思います。
タッチダウン、指が動いた時と、タッチアップの時に、前の座標→今の座標の範囲をdrawLineによって線引きします。
これだけでは画面に反映されないので、再描画イベントを起こすinvalidate();をコールします。

何故ACTION_DOWN時に座標を-1しているかというと、drawLineは座標→同じ座標では描画出来ません。
するとドラッグせずにタップだけした時に線が書かれないので、チョンと押した時にでもラインが引かれるようにしてあります。
本当はこの瞬間だけ場合分けして線と同じ大きさでdrawCiecleするのが良いでしょうが、まぁそこは省略しましょう。

以上の実装をすると、お絵かきがお絵かきが出来る状態になっています。

実行結果


              
・・・何これドロイド君のつもり?

ん・・誰か何か言いました?

本節のプロジェクトはこちら

→分からないことがあれば掲示板で質問して下さい


Portions of this page are modifications based on work created and shared by Google and used according to terms described in the Creative Commons 3.0 Attribution License.

- Remical Soft -