我正在尝试做一个允许用户“绘制”它的视图。现在我所做的是路径,然后我用一条线连接它,但是不能正常工作,它工作缓慢并使事情变得“奇怪”。您可以在此视频http://youtu.be/PUSUTFhDPrM上看到,抱歉,它有点快,但您可以看到我在说什么。
我的实际代码是:
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
private List<List<Point>> _paths = new ArrayList<List<Point>>();
private List<Point> _lastPath;
private Paint _paint = new Paint();
private Path _path = new Path();
public DrawView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
setOnTouchListener(this);
_paint.setColor(Color.BLACK);
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeWidth(5);
_paint.setAntiAlias(true);
}
public DrawView(Context context, AttributeSet attrs) {
super( context, attrs );
setFocusable(true);
setFocusableInTouchMode(true);
setOnTouchListener(this);
_paint.setColor(Color.BLACK);
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeWidth(5);
_paint.setAntiAlias(true);
}
public DrawView(Context context, AttributeSet attrs, int defStyle) {
super( context, attrs, defStyle );
setFocusable(true);
setFocusableInTouchMode(true);
setOnTouchListener(this);
_paint.setColor(Color.BLACK);
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeWidth(5);
_paint.setAntiAlias(true);
}
@Override
protected void onDraw(Canvas canvas) {
for (List<Point> pointsPath : _paths) {
_path.reset();
boolean first = true;
for (int i = 0; i < pointsPath.size(); i += 2) {
Point point = pointsPath.get(i);
if (first) {
first = false;
_path.moveTo(point.x, point.y);
} else if (i < pointsPath.size() - 1) {
Point next = pointsPath.get(i + 1);
_path.quadTo(point.x, point.y, next.x, next.y);
} else {
_path.lineTo(point.x, point.y);
}
}
canvas.drawPath(_path, _paint);
}
}
public boolean onTouch(View view, MotionEvent event) {
Point point = new Point();
point.x = event.getX();
point.y = event.getY();
Log.d(TAG, "point: " + point);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
_lastPath = new ArrayList<Point>();
_lastPath.add(point);
_paths.add(_lastPath);
break;
case MotionEvent.ACTION_MOVE:
_lastPath.add(point);
break;
}
invalidate();
return true;
}
private class Point {
float x, y;
@Override
public String toString() {
return x + ", " + y;
}
}
public void changePaint(int Stroke, int color){
_path.reset();
_paint.setColor(color);
_paint.setStyle(Paint.Style.STROKE);
_paint.setStrokeWidth(Stroke);
_paint.setAntiAlias(true);
}
}
我想知道是否有更好的方法允许用户用手指“画画”或者我可以改进什么来删除此代码中最慢的部分。
答案 0 :(得分:2)
问题可能是您在UI线程上执行此类操作,尝试在后台线程上执行此操作。
答案 1 :(得分:1)
你的抽奖操作没问题。绘图时最糟糕的事情是实例化新对象而你却不这样做。
评论@Atermis的答案,实际上“在后台画画”没有多大意义。 Android中的绘图发生在UI线程上,如果你有大量的绘图计算,那么是的,它可能是有用的,但这里有一些更简单的解决方案:双缓冲区。
您可以使用表面视图和lockCanvas,也可以在内存缓冲区中绘制,然后按照此处的说明在单个操作中显示:http://www.mail-archive.com/android-beginners@googlegroups.com/msg03172.html。
答案 2 :(得分:1)
您可能希望了解MotionEvent
此处的批量处理:http://developer.android.com/reference/android/view/MotionEvent.html
基本上,您可以使用getHistoricalX
和getHistoricalY
获取当前和最后X,Y之间所有坐标的列表。