Android绘制一条线跟随你的手指

我想要做的是绘制一条线,将遵循我的手指。 我创build了一个自定义视图,并且我有一个可以工作的onTouchEvent()

我可以在onDraw()方法中画一条静态的线,而不会有太多的麻烦。

我不确定如何让我的手指移animation线。

  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()上设置坐标,并不断使视图无效,以便小线段绘制?

最后,我只是想用我的手指在屏幕上基本涂鸦进行这个实验。

Solutions Collecting From Web of "Android绘制一条线跟随你的手指"

你只跟踪上下的事件。 跟踪ACTION_MOVE事件。 注意,即使人的手指没有明显移动,它也会连续跟踪。 你的代码应该是这样的:

ACTION_DOWN:存储位置。

ACTION_MOVE:如果位置与存储位置不同,则从存储位置到当前位置绘制一条线,并将存储的位置更新为当前位置。

ACTION_UP:停止。

在ACTION_MOVE位中,检查位置是否离存储位置至less2或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()); } } 

希望这是有帮助的。 如果我减less了太多,有些事情你不要让我知道。

下一步,使对象跟随线!

触摸事件与可获取的指针计数列表相关联,如下所示:

  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是可以在绘制之前被locking的canvas(例如,在multithreading应用程序中)。

对于新手,这段代码将帮助你创build涂鸦图像,并将其导出到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); } } 

另外检查一下Java Path类。 你可以用它来绘制path…当你在屏幕上移动你的手指。 随着每次更新(但是你实现了这一点 – 例如最后一次更新的每一个像素),你将x,y坐标添加到你的path,并通过一个循环重新渲染总path。 只是一个我现在正在玩的想法。

它已经有一段时间了,但这篇文章仍然有一些意见,所以我想我会发布一些有用的东西:

教程如何使一个对象遵循一条线: http : //www.rengelbert.com/tutorial.php?id=182

这是一个很好的免费游戏引擎,上面的教程也使用: http : //libgdx.badlogicgames.com/

希望这可以帮助别人!