基于此问题的答案: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:这不是重复的问题,我在上面解释过!
答案 0 :(得分:9)
您不应该使用onTouchEvent
,不要存储对canvas
的引用,将drawLine
移至
@Override protected void onDraw(Canvas canvas) { ... }
invalidate()
会为您拨打draw()
,然后拨打onDraw()
。
一般情况下:使用onTouchEvent
和onClick
等UI事件来修改视图的状态,然后从这些事件中调用invalidate()
并实现onDraw
,以便始终呈现对象的状态。
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;
}
}
<?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"
/>
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);
}
}
注意:我使用<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
}
}