SurfaceViewを使って、リボンを作成してみる

2回ほど前に作成したリボンですが

リボンを作って指を中心にくるくるする

 Viewで作成していたのですが、今回はsurfaceViewを使ってより早く描画できるようにしてみます。

 

・まずは簡単にViewとSurfaceViewの違いから。

viewに関しては、基本的には静止でinvalidate()を利用することで、再描画をする事ができました。上記のサンプルを作成した際には連続描画をTimerを用いて作成していました。実際にTimerで設定した時間よりも遅くなってしまいましたが、そこまでスピードが遅くなることもなく実装ができていました。

surfaceviewに関してはimplementでSurfaceHolder.Callback,Runnableを読み込む事で、内部にThreadを持ち、surfaceholderで描画用のデータへの描画を簡単にしてくれます。基本の形としては、

surfaceCreated
surfaceChanged
surfaceDestroyed

の三段階を実装します。

この中でthreadを実装する際に

Canvas canvas = sufaceHolder.lockCanvas();
canvas.draw・・・
sufaceHolder.unlockCanvasAndPost(canvas);

としてcanvasのロックを調整する事で描画用の最適化をしてくれるようです。

で、今回作成するのは

で前回の赤一色ではまったく同じものになってしまうので、少し色を変える仕組みを入れてみました。

マニフェストは

特に変更しません。

レイアウトは

直接surfaceviewを配置する

surfaceviewは

public class MainView extends SurfaceView implements SurfaceHolder.Callback,Runnable {
    
    private SurfaceHolder sufaceHolder;
    private Thread thread;
    

    public int _x = 200, _y = 100;
    public float currentX1 = 200, currentY1 = -100;
    public float _xV1 = 0,_yV1 = 0;
    
    Bitmap _bitmap;
    Canvas _canvas;
    Paint paint1;
    
    public MainView(Context context) {
        super(context);
        sufaceHolder = null;
        thread = null;
        getHolder().addCallback(this);
        paint1 = new Paint();
        paint1.setAntiAlias(true);
        paint1.setStrokeWidth(6);
        paint1.setStrokeCap(Paint.Cap.ROUND);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        this.sufaceHolder = holder;
        thread = new Thread(this);
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

        _bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_4444);
        _canvas = new Canvas(_bitmap);
        _canvas.drawColor(Color.WHITE);

        if (thread != null) {

            thread.start();
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        thread = null;
        BOOL = false;
    }
    Boolean BOOL = true;
    
    int _count1 = (int)(300*Math.random());
    int _count2 = (int)(300*Math.random());
    int _count3 = (int)(300*Math.random());
    
    public void run() {
        while (BOOL) {
            _count1++;
            _count2 += 2;
            _count3 += 3;
            paint1.setColor(Color.rgb((int)(128+127*Math.sin(Math.PI*2/360*_count1)), (int)(128+127*Math.sin(Math.PI*2/360*_count2)), (int)(128+127*Math.sin(Math.PI*2/360*_count3))));
            _xV1 += (_x - currentX1)/12.0f;
            _yV1 += (_y - currentY1)/12.0f;
            _xV1 *= 0.9;
            _yV1 *= 0.9;
            currentX1 += _xV1;
            currentY1 += _yV1;
            paint1.setStrokeWidth(Math.abs(_yV1)/10.0f+Math.abs(_xV1)/10.0f);
            _canvas.drawLine((int)currentX1, (int)currentY1, (int)(currentX1-_xV1),(int)(currentY1-_yV1), paint1);
            Canvas canvas = sufaceHolder.lockCanvas();
            canvas.drawBitmap(_bitmap, 0, 0, null);
            sufaceHolder.unlockCanvasAndPost(canvas);
        }
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            _x = (int) event.getX();
            _y = (int) event.getY();
            break;
        case MotionEvent.ACTION_MOVE:
            _x = (int) event.getX();
            _y = (int) event.getY();
            break;
        case MotionEvent.ACTION_UP:
            break;
        default:
            break;
        }
        return true;
    }
    
    
}

メインのクラスは

setContentView(R.layout.main);
MainView surfaceView = new MainView(this);
setContentView(surfaceView);

以上です。

 

前後の記事

前の記事:

次の記事:

関連の記事

コメントの投稿

  • サイト内検索

新作アプリの紹介

関連サイトの紹介

アンドロイドアプリ開発TIPS
きぐるみカメラ
ふらいぱん
アンドロイドのデザイン集
Page top↑