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() и постоянно отменяет вид Итак, маленькие сегменты линии рисуют?

в конце концов, я просто хочу иметь возможность в основном рисовать на экране, используя мой палец для этот эксперимент.

6 ответов


вы отслеживаете только вверх и вниз события. Отслеживайте событие ACTION_MOVE тоже. Остерегайтесь, что он будет отслеживать непрерывно, даже если палец человека, по-видимому, не движется. Ваш код должен идти примерно так:

ACTION_DOWN: позиция магазина.

ACTION_MOVE: если позиция отличается от сохраненной позиции, нарисуйте линию от сохраненной позиции до текущей позиции и обновите сохраненную позицию до текущей.

выполняется: стоп.

In бит ACTION_MOVE, было бы неплохо проверить, находится ли позиция по крайней мере на расстоянии 2 или 3 пикселей от сохраненной позиции. Если вы собираетесь сохранить все точки графика, чтобы вы могли что-то сделать с данными позже, то, возможно, увеличите это до 10 пикселей, чтобы вы не получили сотни точек для простой линии.


вот что я закончил делать. Надеюсь, это поможет некоторым другим новичкам начать работу.

у меня есть класс 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, которые выглядят следующим образом:

    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());
        }
    }

надеюсь это полезно. Если я обрезал слишком много, и есть то, что вы не получите, дайте мне знать.

следующий шаг, делая объект следовать линии!


событие касания связано со списком счетчиков указателей, которые можно получить следующим образом:

     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 - это холст, который может потребоваться заблокировать (например, в многопоточном приложении), до рисования на нем.


для новичков этот код поможет вам создать изображение каракули и экспортировать его в Png-изображение вот это код и это класс Activity с содержит класс View тоже..

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);
    }

}

также проверьте класс пути Java. Вы можете использовать это, чтобы нарисовать путь...как вы перемещаете палец по экрану. с каждым обновлением (однако вы реализуете это - каждые столько пикселей из последнего обновления,например) вы добавляете координату x, y в свой путь и повторно визуализируете общий путь через цикл. просто идея, с которой я сейчас играю.


прошло некоторое время, но этот пост все еще получает некоторые взгляды, поэтому я решил, что опубликую некоторые полезные вещи:

учебник о том, как заставить объект следовать линии: http://www.rengelbert.com/tutorial.php?id=182

Это хороший бесплатный игровой движок, который использует вышеприведенный учебник: http://libgdx.badlogicgames.com/

надеюсь, это поможет кому-то!