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/

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

Intereting Posts
Android: как деформировать изображения? Исключение Java JavaLaunchHelper при выполнении тестов Заполнение не работает с определенным фоновым ресурсом Фоновое изображение на мобильном телефоне не правильно соответствует экрану Почему Android webview показывает «Далее» на клавиатуре, только если type = «number», а не с типом = «текст»? Android LinkedIn SDK создает непригодные токены доступа Как преодолеть Android Studio не может разрешить символ для классов Android Как использовать центр представления как контрольную точку внутри RelativeLayout Можем ли мы отображать инструмент выбора стиля старого стиля (Pre Lollipop Time Picker) в ледяных устройствах Android M + Retrofit + JSON: невозможно создать конструктор полей Как передать текстуры из одного контекста OpenGL в другой Ошибка: невозможно получить заблокированный буффер, очень вероятный клиент пытается заблокировать больше, чем maxImages buffers Пользовательский тост в android: простой пример Как изменить размер текста в зависимости от размера виджета в текстовом виде в приложении? Android. Как я могу перемещать NavigationDrawer из тестовой библиотеки Espresso?