LoginSignup
3
3

More than 5 years have passed since last update.

画面を掃除するようなView:Android

Posted at

今回、画面が徐々に汚くなる→指で掃除をする、みたいなViewを作成したので、備忘録的に投稿します。
ちょろちょろっと作成したものなので雑な作りです。

プログラム

import java.util.Random;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuffXfermode;
import android.graphics.PorterDuff;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;

public class DustView extends View implements OnTouchListener {

    private Bitmap mWallBitmap; // 透明なビットマップ
    private Canvas mWallCanvas; // キャンバス
    private Path mPath = new Path();
    private int dustLen = 0;
    private long dustAddTime = 0;
    private int displayWidth;
    private int displayHeight;
    private Paint dustPaint;
    private Handler dustHandler;

    /**
     * コンストラクタ
     * @param context コンテキスト
     */
    public DustView(Context context, int dustLen, long dustAddTime) {
        super(context);
        // 煤の描画数と描画時間をセットする
        this.dustLen= dustLen;
        this.dustAddTime= dustAddTime;
        // タッチリスナーをセットする
        this.setOnTouchListener(this);
    }

    /**
     * ビューサイズが変更された
     */
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {

        dustHandler = new Handler();

        // ディスプレイサイズの取得
        displayWidth = w;
        displayHeight = h;

        // 煤のペイントを作る
        dustPaint = new Paint();
        dustPaint.setColor(0x88000000);

        // Bitmapを新しく作る
        this.mWallBitmap = null;
        this.mWallBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);

        // キャンバスを新しく作る
        this.mWallCanvas = null;
        this.mWallCanvas = new Canvas(this.mWallBitmap);

        // 描画を開始する
        autoRun();

        super.onSizeChanged(w, h, oldw, oldh);
    }

    /**
     * 描画通知
     */
    @Override
    protected void onDraw(Canvas canvas) {

        // 落書き用Bitmapに書かれた内容を表へ転送
        canvas.drawBitmap(this.mWallBitmap, 0, 0, null);

        super.onDraw(canvas);
    }


    /**
     * タッチされた時の処理
     */
    @Override
    public boolean onTouch(View v, MotionEvent event) {

        // タッチされた座標を取り出す
        float x = event.getX();
        float y = event.getY();

        // アクションを取り出し
        int action = event.getAction();

        switch (action) {

            // タッチ開始
            case MotionEvent.ACTION_DOWN:

                // パスをリセットしてから新しい座標をセット
                this.mPath.reset();
                this.mPath.moveTo(x, y);

                // ここまでの状態でパスに沿って線を書く。
                // 最初だから○が描かれるだけ
                this.drawPath(this.mWallCanvas, this.mPath);

                // 再描画通知
                this.invalidate();
                return true;    // ←trueを返さないとACTION_UPがやってこない

            // タッチ終了
            case MotionEvent.ACTION_UP:

                // ここまでのパスをセット
                this.mPath.lineTo(x, y);

                // パスに沿って線を描く
                this.drawPath(this.mWallCanvas, this.mPath);

                // 再描画通知
                this.invalidate();
                break;

            // タッチしたまま指が動かされた
            case MotionEvent.ACTION_MOVE:

                // パスをセットする
                this.mPath.lineTo(x, y);

                // ここまでの状態を書き込む
                this.drawPath(this.mWallCanvas, this.mPath);

                // 再描画通知
                this.invalidate();
                break;
        }

        return false;
    }

    /**
     * パスに沿って線を書く
     * @param canvas キャンバス
     * @param path パス
     */
    private void drawPath(Canvas canvas, Path path) {

        // 線を書くためのペイント
        Paint paint = new Paint();
        paint.setDither(true);
        paint.setAntiAlias(true);

        // これをすると塗りつぶす方の色が優先される
        // 背景のアルファを無視して下のレイアウトが見えるようになる
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
        paint.setColor(Color.argb(0, 0x00, 0, 0));

        // 線を引く設定(角をどうするかとか)
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeCap(Paint.Cap.ROUND);
        paint.setStrokeJoin(Paint.Join.ROUND);

        // 太めに
        paint.setStrokeWidth(120);
        canvas.drawPath(path, paint);
    }

    private void autoRun(){
        dustHandler.postDelayed(new Runnable() {

            @Override
            public void run() {
                addDust();
                autoRun();
            }
        }, dustAddTime);
    }

    private void addDust(){
        //Randomクラスのインスタンス化
        for(int i = 0; i < dustLen; i++)
        {
            Random rnd = new Random();
            int widthRan = rnd.nextInt(displayWidth);
            int heightRan = rnd.nextInt(displayHeight);
            this.mWallCanvas.drawCircle(widthRan, heightRan, 2, dustPaint);
        }
        this.invalidate();
    }

}
3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3