为什么它变慢?还是奇怪的?

时间:2013-04-14 18:27:36

标签: android android-canvas android-view

我正在尝试做一个允许用户“绘制”它的视图。现在我所做的是路径,然后我用一条线连接它,但是不能正常工作,它工作缓慢并使事情变得“奇怪”。您可以在此视频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);

}

}

我想知道是否有更好的方法允许用户用手指“画画”或者我可以改进什么来删除此代码中最慢的部分。

3 个答案:

答案 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

基本上,您可以使用getHistoricalXgetHistoricalY获取当前和最后X,Y之间所有坐标的列表。