5

嘿,我想用画布画一条不同图案的线。

任何想法或建议都值得赞赏..!!!!

提前致谢。

4

2 回答 2

3

你必须使用Path.Docs 说:

Path 类封装了由直线段、二次曲线和三次曲线组成的复合(多轮廓)几何路径。...

例如,您可以扩展 aview并将触摸事件位置添加到视图path的方法中onTouchEvent(MotionEvent event)。然后您必须生成对应于最新触摸事件的随机位置并将它们添加到路径的其他实例。最后在onDraw()视图的方法中,绘制所有路径。我希望这个片段能帮助你理解我的想法:

public class NetCanvas extends View {

    private static final double MAX_DIFF = 15;
    Path path0 = new Path();
    Path path = new Path();
    private Paint p0;
    private Paint p;

    public NetCanvas(Context context) {
        super(context);
        p0 = new Paint();
        p0.setShader(new LinearGradient(0, 0, 230, getHeight(), Color.GREEN,
                Color.RED, Shader.TileMode.CLAMP));
        p0.setStyle(Style.STROKE);

        p = new Paint();
        p.setShader(new LinearGradient(0, 0, 230, getHeight(), Color.BLUE,
                Color.MAGENTA, Shader.TileMode.CLAMP));
        p.setStyle(Style.STROKE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float x0 = event.getX();
        float y0 = event.getY();
        float x = generateFloat(event.getX());
        float y = generateFloat(event.getY());

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            path0.moveTo(x0, y0);
            path0.lineTo(x0, y0);

            path.moveTo(x, y);
            path.lineTo(x, y);
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            path0.lineTo(x0, y0);

            path.lineTo(x, y);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            path0.lineTo(x0, y0);

            path.lineTo(x, y);
        }
        invalidate();
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawPath(path0, p0);
        canvas.drawPath(path, p);
    }

    private float generateFloat(Float f){
        double d = (Math.signum(2*Math.random() - 1)) * Math.random() * MAX_DIFF;
        return (float) (f + d);
    }
}

在上面的代码中,我使用了两个path,但你可以使用三个或更多。同样结果,取决于你在屏幕上的手指速度。例如:
在此处输入图像描述

或者它可能看起来像这样:

在此处输入图像描述

编辑:

上面的 class( NetCanvas) 扩展View,因此您可以创建它的实例并使用该实例,就像其他视图一样。例如,您可以简单地将它的实例设置为ContentView您的 Activity。这里我覆盖onCreate()Activity 的方法:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new NetCanvas(this));
    }

尽管您可以更改NetCanvas以扩展SurfaceView其他一些更改。

于 2013-01-12T04:45:40.450 回答
1

我更改NetCanvas为在您的问题中绘制一个看起来像第二张图像的形状:

public class NetCanvas1 extends View {

    Path path0 = new Path();
    private Paint p0;
    private int points_Num = 20;
    private int first_Points_Num = 5;

    public NetCanvas1(Context context) {
        super(context);
        p0 = new Paint();
        p0.setShader(new LinearGradient(0, 0, 230, getHeight(), Color.GREEN,
                Color.RED, Shader.TileMode.CLAMP));
        p0.setStyle(Style.STROKE);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float x0 = event.getX();
        float y0 = event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            path0.moveTo(x0, y0);
            path0.lineTo(x0, y0);

        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            path0.lineTo(x0, y0);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            path0.lineTo(x0, y0);
            invalidate();
        }
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawPath(path0, p0);
        FlaotPoint[] pointArray = getPoints();
        try {
            for (int i = 0; i < first_Points_Num; i++) {
                for (int j = i; j < pointArray.length; j++) {
                    canvas.drawLine(pointArray[i].getX(), pointArray[i].getY(),
                            pointArray[j].getX(), pointArray[j].getY(), p0);
                }
            }
            path0.reset();
        } catch (Exception e) {
        }
    }

    private FlaotPoint[] getPoints() {
        FlaotPoint[] pointArray = new FlaotPoint[points_Num];
        PathMeasure pm = new PathMeasure(path0, false);
        float length = pm.getLength();
        float distance = 0f;
        float speed = length / points_Num;
        int counter = 0;
        float[] aCoordinates = new float[2];

        while ((distance < length) && (counter < points_Num)) {
            // get point from the path
            pm.getPosTan(distance, aCoordinates, null);
            pointArray[counter] = new FlaotPoint(aCoordinates[0],
                    aCoordinates[1]);
            counter++;
            distance = distance + speed;
        }

        return pointArray;
    }

    class FlaotPoint {
        float x, y;

        public FlaotPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }
    }
}

结果取决于 的值points_Numfirst_Points_Num以及与 for 循环中的线相连的点的顺序:

for (int i = 0; i < first_Points_Num; i++) {
                for (int j = i; j < pointArray.length; j++) {
                    canvas.drawLine(pointArray[i].getX(), pointArray[i].getY(),
                            pointArray[j].getX(), pointArray[j].getY(), p0);
                }
            }

您可以更改每个变量的值或点的顺序以更改结果。结果可能如下所示:

在此处输入图像描述 在此处输入图像描述

我的想法很简单:从路径获取点并将它们与线连接。如果您想查看有关从路径获取点的更多详细信息,这是在getPoints()方法中完成的,您可以看到这个答案及其参考。我希望这对您有所帮助。

于 2013-01-15T21:11:25.557 回答