web-dev-qa-db-ja.com

Android指に沿って線を引く

指に沿うように線を引きたい。カスタムビューを作成しましたが、機能するonTouchEvent()があります。

onDraw()メソッドで静的な線を問題なく描画できます。

指の動きに合わせて線を引く方法はわかりません。

_  public boolean onTouchEvent(MotionEvent event) {
        super.onTouchEvent(event);
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN: {
            Log.e(TAG, " - DOWN -");
            Log.e(TAG, " getX: " + event.getX());
            break;
        }
        case MotionEvent.ACTION_UP: {
            Log.e(TAG, " - UP -");
            Log.e(TAG, " getX: " + event.getX());
            break;
        }
        }
        return true;
    }
_

しばらくやってきた皆さんに何かヒントはありますか?

onTouchEvent()に座標を設定し、ビューを常に無効にして小さな線分を描く必要がありますか?

結局、私はこの実験のために基本的に私の指を使って画面上で落書きできるようにしたいだけです。

15
jacklin

Upとdownのイベントのみを追跡しています。 ACTION_MOVEイベントも追跡します。人の指が明らかに動いていない場合でも、継続的に追跡することに注意してください。コードは次のようになります。

ACTION_DOWN:ストアの位置。

ACTION_MOVE:位置が保存された位置と異なる場合、保存された位置から現在の位置まで線を引き、保存された位置を現在の位置に更新します。

ACTION_UP:やめて。

ACTION_MOVEビットで、位置が格納された位置から少なくとも2または3ピクセル離れているかどうかを確認することをお勧めします。すべてのプロットポイントを保存して、後でデータを使用して何かを実行できるようにする場合は、10ピクセルに増やすと、単純な線で何百ものポイントがなくなることはありません。

30
Andrew Smith

これが私がやったことです。これが他の初心者が始めるのに役立つことを願っています。

画面上で移動したいオブジェクトを表すSpriteクラスがあります。

   public class Sprite {
    private final String TAG = "Sprite";
    private Drawable drawable;
    private int x; // the X coordinate
    private int y; // the Y coordinate
    private boolean touched; // if droid is touched/picked up
    private Speed speed; // the speed with its directions

    public Sprite(Drawable drawable, int x, int y) {
        this.drawable = drawable;
        this.x = x;
        this.y = y;
        this.speed = new Speed();
    }

    public void draw(Canvas canvas) {
        drawable.setBounds(new Rect(x, y, x+drawable.getIntrinsicWidth(), y+drawable.getIntrinsicHeight()));
        drawable.draw(canvas);
    }

    public void move() {
        if (!touched) {
            x += (speed.getXv() * speed.getxDirection());
            y += (speed.getYv() * speed.getyDirection());
        }
    }

    public void handleActionDown(int eventX, int eventY) {
        if (eventX >= (x - bitmap.getWidth() / 2) && (eventX <= (x + bitmap.getWidth() / 2))) {
            if (eventY >= (y - bitmap.getHeight() / 2) && (y <= (y + bitmap.getHeight() / 2))) {
                // droid touched
                setTouched(true);
            } else {
                setTouched(false);
            }
        } else {
            setTouched(false);
        }
    }
}

次に、メインゲームループがあります。それはループし、私のmainPanelのrenderおよびupdateメソッドを呼び出します。

    public void render(Canvas canvas) {
    canvas.drawColor(Color.BLACK);
    Sprite.draw(canvas);
}

public void update() {
    Sprite.move();
}

スプライトが移動する位置は、モーションイベントキャプチャで処理されます。

        if (event.getAction() == MotionEvent.ACTION_MOVE) {
        // the gestures
        if (Sprite.isTouched()) {
            Sprite.setX((int) event.getX());
            Sprite.setY((int) event.getY());
        }
    }

うまくいけば、それは役に立ちます。トリムしすぎて、知らないことがあったら教えてください。

次のステップでは、オブジェクトに線を引きます!

9
jacklin

タッチイベントは、次のように取得可能なポインターカウントのリストに関連付けられています。

     int p = event.getPointerCount();

これらを繰り返してポイントを描画すると、連続した線が表示される可能性があります

if (event.getAction() == MotionEvent.ACTION_MOVE
    || event.getAction() == MotionEvent.ACTION_DOWN) {

  int p = event.getPointerCount();
     for (int i = 0; i < p; i++) { 
       c.drawPoint(event.getX(i), event.getY(i), Paint);
     }
}

Paintはすでに設定されており、cはキャンバスであり、描画する前にロックする必要がある(マルチスレッドアプリケーションなど)と仮定します。

3
heyNow

初心者の場合、このコードは落書き画像を作成してPng画像にエクスポートするのに役立ちます。ここでは 完全なコード で、これにはアクティビティクラスのあるビュークラスも含まれています。

public class MainActivity extends Activity {
    private Bitmap DrawBitmap;
    private Canvas mCanvas;
    private Path mPath;
    private Paint DrawBitmapPaint;
    RelativeLayout Rl;
    CustomView View;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        View = new CustomView(this);
        Rl = (RelativeLayout) findViewById(R.id.Rel);
        Rl.addView(View);
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(getResources()
                .getColor(Android.R.color.holo_green_dark));
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(20);

    }

    private Paint mPaint;

    public class CustomView extends View {

        @SuppressWarnings("deprecation")
        public CustomView(Context c) {

            super(c);
            Display Disp = getWindowManager().getDefaultDisplay();
            DrawBitmap = Bitmap.createBitmap(Disp.getWidth(), Disp.getHeight(),
                    Bitmap.Config.ARGB_4444);

            mCanvas = new Canvas(DrawBitmap);

            mPath = new Path();
            DrawBitmapPaint = new Paint(Paint.DITHER_FLAG);
        }

        @Override
        protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            setDrawingCacheEnabled(true);
            canvas.drawBitmap(DrawBitmap, 0, 0, DrawBitmapPaint);
            canvas.drawPath(mPath, mPaint);
            canvas.drawRect(mY, 0, mY, 0, DrawBitmapPaint);
        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }

        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
                mX = x;
                mY = y;
            }
        }

        private void touch_up() {
            mPath.lineTo(mX, mY);

            mCanvas.drawPath(mPath, mPaint);

            mPath.reset();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touch_start(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                invalidate();
                break;
            }
            return true;
        }

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        mPaint.setXfermode(null);
        switch (item.getItemId()) {
        case R.id.erase: 
               mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
               break;
        case R.id.DELETE: 
             View =  new CustomView(this);
               break;
        case R.id.draw: 
               mPaint.setXfermode(null);

               break;
        case R.id.Save:
            String pattern = "mm ss";
            SimpleDateFormat formatter = new SimpleDateFormat(pattern);
            String time = formatter.format(new Date());
            String path = ("/d-codepages" + time + ".png");

            File file = new File(Environment.getExternalStorageDirectory()
                    + path);

            try {
                DrawBitmap.compress(Bitmap.CompressFormat.PNG, 100,
                        new FileOutputStream(file));
                Toast.makeText(this, "File Saved ::" + path, Toast.LENGTH_SHORT)
                        .show();
            } catch (Exception e) {
                Toast.makeText(this, "ERROR" + e.toString(), Toast.LENGTH_SHORT)
                        .show();
            }

        }
        return super.onOptionsItemSelected(item);
    }

}
2
sarath kumar

Java Pathクラス。パスクラスを確認してください。これを使用して、画面上で指を動かすと、パスを描画できます。更新を行うたびに(ただし、これを実装しますが、たとえば、最後の更新)は、x、y座標をパスに追加し、ループを介してパス全体を再レンダリングします。

1
cspam

それはしばらくの間ですが、この投稿はまだいくつかのビューを持っているので、私はいくつかの役立つものを投稿すると思いました:

オブジェクトを次のようにする方法のチュートリアル: http://www.rengelbert.com/tutorial.php?id=182

これは、上記のチュートリアルでも使用されている優れた無料ゲームエンジンです。 http://libgdx.badlogicgames.com/

これが誰かを助けることを願っています!

1
jacklin