2013-04-14 55 views
0

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

} 

} 

我要的是知道是否有更好的方法来让用户“画”用手指或者我有什么可以改善删除这个最慢的部分码。

回答

1

你的绘制操作很好。绘画时要做的更糟糕的事情是实例化新对象,而你不这样做。

要评论@ Atermis的答案,实际上“绘制背景”没有多大意义。如果在UI线程中绘制Android线程,如果你有大量计算绘制,那么是的,这可能是有用的,但这里更简单的解决方案是:双缓冲区。

要么你可以使用表面视图和lockCanvas或者你可以在一个内存缓冲区中绘制,然后在一个单一的操作中显示它,如下所述:http://www.mail-archive.com/[email protected]/msg03172.html

+0

如果我实现lockCanvas,我的线将在finge触摸屏幕的同时绘制? –

2

可能问题在于您在UI线程上执行此操作,请尝试在后台线程上执行此操作。

+0

我该怎么做?我如何在后台使用线程? –

+1

看看这个视频http://www.youtube.com/watch?v=Z2YogvILjvo这是一个在画布上绘制东西的好例子http://android-journey.blogspot.co.il/2010/02 /android-2d-simple-example.html – Artemis