Canvas.drawLines显示脱节的段

时间:2011-05-29 10:40:37

标签: java android drawing gesture

  

可能重复:
  Android How to draw a smooth line following your finger

我是Android和Java编程的新手,并且一直在玩移动应用程序开发。我最近创建了一个视图,它简单地保持与用户的手指动作一致地绘制线条。但是,我在使用Canvas.drawLines方法时遇到了一些麻烦。

我没有在所有点之间获得连续的线条,而是获得了更多的虚线模式,并且各段之间有间隔:

Broken Line Segments in Canvas.DrawLines

以下是一组示例数据和简单代码,用于重现问题(点数据来自真正的手指滑动):

public class SomeView extends android.view.View 
{
    private float[] _data = { 292.36545f, 104.37576f, 285.3567f, 112.39249f, 274.34293f, 113.39456f, 254.3179f, 115.39874f, 248.3104f, 116.40082f, 228.28535f, 118.405f, 214.26784f, 119.407104f, 211.26408f, 119.407104f, 204.25533f, 120.40918f, 202.25282f, 120.40918f, 201.25157f, 121.411255f, 199.24907f, 124.41754f, 197.24657f, 125.41962f, 196.24532f, 130.43005f, 195.24406f, 139.44885f, 197.24657f, 144.45929f };
    private Paint _paint;

    public SomeView( Context c, AttributeSet attrs)
    {
        super( c, attrs );
        _paint = new Paint();
        _paint.setColor(Color.BLUE);
        _paint.setStrokeWidth(6);   
    }   

    @Override
    public void onDraw(Canvas canvas)
    {       
        canvas.drawLines( _data, _paint);
    }           
}

在绘制出每个点并将其覆盖在线上之后,我意识到问题实际上是每个点都没有连接,只有每两个点。而不是将点1连接到点2到点3,依此类推,方法是连接1到2然后3到4,如下所示:

enter image description here

我可以几乎得到我想要的东西,再次绘制drawLines并再次提供一个偏移,以便其他对也被绘制在一起,但这似乎效率低下且通常笨重对我来说,线仍然不是完全平滑(角落略微不稳定)。

所以,我的问题是;我做错了什么?如何给出一些简单,流畅的线条?哎呀,忘了点,如果有更好的方法用线跟踪用户的手指,我全都耳朵。提前谢谢。

2 个答案:

答案 0 :(得分:12)

您获得的正是drawLines文档中指定的内容。

执行所需操作的一种方法是根据该数据构建Path,并使用drawPath而不是drawLines。类似的东西:

Path _path = new Path();
_path.moveTo(_data[0], _data[1]);
for (int i=2; i<_data.length; i+=2) {
  _path.lineTo(_data[i], _data[i+1]);
}

然后用:

画出来
_canvas.drawPath(_path, _paint)

来自Path文档:

  

Path类封装由直线段,二次曲线和三次曲线组成的复合(多个轮廓)几何路径。它可以用canvas.drawPath(path,paint)绘制,填充或描边(基于 paint的样式

所以你可能不得不改变你的油漆风格以获得正确的效果。

答案 1 :(得分:3)

我今晚刚遇到这个问题。对于其他任何面临这种情况的人来说,问题是Android不会从第1点到第2点,然后从第2点到第3点,第3点到第4点等等。它将绘制点1到2,然后点3到4等等。所以你也可以将前一点推到你使用的任何数据结构中两次(我使用Vector)。所以:

private Vector<Float> mPoints = new Vector<Float>();
private float mLastX = Float.NaN;
private float mLastY = Float.NaN;

public void addPoint(float x, float y) {
    if (mLastX == Float.NaN || mLastY == Float.NaN) {
        mLastX = x;
        mLastY = y;
    } else {
        mPoints.add(mLastX);
        mPoints.add(mLastY);
        mPoints.add(x);
        mPoints.add(y);

        mLastX = x;
        mLastY = y;
    }
}

然后确保将mPoints转换为float []并将其传递给canvas.drawLines()