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);
以上です。