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

时间:2014-12-05 17:11:03

标签: java android

基于此问题的答案:Android drawing a line to follow your finger

我尝试了我的解决方案(参见代码),但我得到的形状像意大利面。如何摆脱以前的线?我想在Microsoft Paint中绘制一条直线。

这是我的代码:

@Override
public boolean onTouchEvent(MotionEvent event) {



    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:

          downx = event.getX();
          downy = event.getY();
        invalidate();

        break;
    case MotionEvent.ACTION_MOVE:
        upx = event.getX();
        upy = event.getY();
        mCanvas.drawLine(downx, downy, upx, upy, mPaint);

        invalidate();

        break;
    case MotionEvent.ACTION_UP:
        upx = event.getX();
          upy = event.getY();                 
         mCanvas.drawLine(downx, downy, upx, upy, mPaint);
        invalidate();

        break;
    }
    return true;
}

谢谢大家!

PS:这不是重复的问题,我在上面解释过!

4 个答案:

答案 0 :(得分:9)

您不应该使用onTouchEvent,不要存储对canvas的引用,将drawLine移至

@Override protected void onDraw(Canvas canvas) { ... }

invalidate()会为您拨打draw(),然后拨打onDraw()

一般情况下:使用onTouchEventonClick等UI事件来修改视图的状态,然后从这些事件中调用invalidate()并实现onDraw,以便始终呈现对象的状态。

FingerLine.java

import android.content.Context;
import android.graphics.*;
import android.graphics.Paint.Style;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.*;

public class FingerLine extends View {
    private final Paint mPaint;
    private float startX;
    private float startY;
    private float endX;
    private float endY;

    public FingerLine(Context context) {
        this(context, null);
    }

    public FingerLine(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Style.STROKE);
        mPaint.setColor(Color.RED);
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(startX, startY, endX, endY, mPaint);
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = event.getX();
                startY = event.getY();
                // Set the end to prevent initial jump (like on the demo recording)
                endX = event.getX();
                endY = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                endX = event.getX();
                endY = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                endX = event.getX();
                endY = event.getY();
                invalidate();
                break;
        }
        return true;
    }
}

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<net.twisterrob.android.view.FingerLine
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

MainActivity.java

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

结果

example

注意:我使用<application android:theme="@style/Theme.AppCompat.Light">,但我认为这不会有所作为。

答案 1 :(得分:0)

您需要在线条绘制代码调用Canvas.drawColor(Color.WHITE)之前在onDraw()函数中重置视图的背景颜色,将WHITE替换为您的背景颜色。或者你可以在任何其他代码之前调用onDraw()中的super.onDraw(canvas)函数。

很抱歉没有例子,我是通过手机写的。

答案 2 :(得分:0)

这是使线条跟随手指的解决方案。 (并且之后不会消失)

import android.content.Context;
import android.graphics.*;
import android.graphics.Paint.Style;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.*;

public class FingerLine extends View {
    private final Paint mPaint;
    private float startX;
    private float startY;
    private float endX;
    private float endY;
    public Canvas mCanvas;

    public FingerLine(Context context) {
        this(context, null);
        mBitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
                         }else {
                             mBitmap = Bitmap.createBitmap(height, height,     Bitmap.Config.ARGB_8888);                         
                         }
        mCanvas = new Canvas(mBitmap);
    }

    public FingerLine(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Style.STROKE);
        mPaint.setColor(Color.RED);
    }

    @Override protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(startX, startY, endX, endY, mPaint);
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = event.getX();
                startY = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_MOVE:
                endX = event.getX();
                endY = event.getY();
                invalidate();
                break;
            case MotionEvent.ACTION_UP:
                endX = event.getX();
                endY = event.getY();
                mcanvas.drawLine(startX, startY, endX, endY, mPaint);
                invalidate();
                break;
        }
        return true;
    }
}

答案 3 :(得分:0)

这是 kotlin 版本的答案..

import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View

class FingerLineView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private var mPaint: Paint = Paint(Paint.ANTI_ALIAS_FLAG)
    private var startX = 0f
    private var startY = 0f
    private var endX = 0f
    private var endY = 0f

    init {
        mPaint.style = Paint.Style.STROKE
        mPaint.color = Color.RED
        mPaint.strokeWidth = 4f
        mPaint.strokeCap = Paint.Cap.ROUND
    }

    override fun onDraw(canvas: Canvas?) {
        super.onDraw(canvas)
        canvas?.drawLine(startX, startY, endX, endY, mPaint)
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when (event!!.action) {
            MotionEvent.ACTION_DOWN -> {
                startX = event.x
                startY = event.y
                // Set the end to prevent initial jump (like on the demo recording)
                endX = event.x
                endY = event.y
                invalidate()
            }
            MotionEvent.ACTION_MOVE -> {
                endX = event.x
                endY = event.y
                invalidate()
            }
            MotionEvent.ACTION_UP -> {
                endX = event.x
                endY = event.y
                invalidate()
            }
        }
        return true
    }
}