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

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

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

ACTION_DOWN: Сохранить позицию.

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

ACTION_UP: Остановить.

В бит 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); } } } 

Тогда у меня есть основной игровой цикл. Это проходит через вызовы и методы myPanel рендеринга и обновления, которые выглядят следующим образом:

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

Для новичков этот код поможет вам создать изображение doodle и экспортировать его в Png-изображение здесь. Полный код и этот класс Activity With содержит класс 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 Path. Вы можете использовать это, чтобы рисовать путь … при перемещении пальца по экрану. С каждым обновлением (однако вы реализуете это – каждый так много пикселей от последнего обновления, например) вы добавляете координату x, y в свой Путь и повторно представляете полный путь через цикл. Просто идея, с которой я сейчас играю.

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

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

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

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