Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/228.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在android中画一条平滑的线并逐渐变小_Android_Android Widget - Fatal编程技术网

在android中画一条平滑的线并逐渐变小

在android中画一条平滑的线并逐渐变小,android,android-widget,Android,Android Widget,我试图实现一个简单的可绘制视图。 现在我正在用这个方法画一条平滑的线 结果是这样的: 我不知道当用户快速移动手指时,如何才能逐渐画出一条小的线。与此示例相同: 你知道我怎样才能得到这个结果吗?(任何方式,引擎或开源)。现在,我正在考虑实现我自己的“quadTo”方法。但我认为这会很慢(或者超过我的能力)。因为它是Android SDK上的本机方法 谢谢你的帮助 这是我的工具,用于为需要它的任何人提供简单的可绘制视图: public class TestView extends LinearL

我试图实现一个简单的可绘制视图。 现在我正在用这个方法画一条平滑的线

结果是这样的:

我不知道当用户快速移动手指时,如何才能逐渐画出一条小的线。与此示例相同:

你知道我怎样才能得到这个结果吗?(任何方式,引擎或开源)。现在,我正在考虑实现我自己的“quadTo”方法。但我认为这会很慢(或者超过我的能力)。因为它是Android SDK上的本机方法

谢谢你的帮助

这是我的工具,用于为需要它的任何人提供简单的可绘制视图:

public class TestView extends LinearLayout{

private static final String TAG = "TestView";
private PointF previousPoint;
private PointF startPoint;
private PointF currentPoint;
private static final float STROKE_WIDTH = 5f;

private static final float HALF_STROKE_WIDTH = STROKE_WIDTH / 2;

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint paintBm = new Paint(Paint.ANTI_ALIAS_FLAG);
private Bitmap bmp;
private Canvas canvasBmp;
private Path path;
private int paintSize = 25;

public TestView(Context context, AttributeSet attrs) {
    super(context, attrs);

    this.setWillNotDraw(false);
    paint.setAntiAlias(true);

    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(STROKE_WIDTH);
    paint.setColor(Color.BLACK);
    //paint.setAlpha(100);

    paintBm.setAntiAlias(true);

    paintBm.setStyle(Paint.Style.STROKE);
    paintBm.setStrokeJoin(Paint.Join.ROUND);
    paintBm.setStrokeCap(Paint.Cap.ROUND);
    paintBm.setStrokeWidth(STROKE_WIDTH);
    paintBm.setColor(Color.BLACK);
    paintBm.setAlpha(100);
    path = new Path();
    //paint.setPathEffect(new CornerPathEffect(2));
}

public TestView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    paint.setAntiAlias(true);

    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setStrokeWidth(STROKE_WIDTH);
    paint.setColor(Color.BLACK);

    path = new Path();
    //paint.setPathEffect(new CornerPathEffect(2));
}



@Override
protected void onLayout(boolean changed, int left, int top, int right,
        int bottom) {
    // TODO Auto-generated method stub
    super.onLayout(changed, left, top, right, bottom);
    if(bmp == null){
        bmp = Bitmap.createBitmap(right-left,bottom-top,Bitmap.Config.ARGB_8888);
        canvasBmp = new Canvas(bmp);

    }
}
@Override
public boolean onTouchEvent(MotionEvent event) {
    //printSamples(event);
    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        currentPoint = new PointF(event.getX(), event.getY());
        previousPoint = currentPoint;
        startPoint = previousPoint;
        path.reset();
        break;

    case MotionEvent.ACTION_MOVE:
        startPoint = previousPoint;
        previousPoint = currentPoint;
        currentPoint = new PointF(event.getX(), event.getY());
        int historySize = event.getHistorySize();
        for(int i = 0; i < historySize; i++){

        }



        drawLine(canvasBmp, path, paint, previousPoint, currentPoint);
        //path.moveTo(currentPoint.x, currentPoint.y);
        break;
    case MotionEvent.ACTION_UP:
        startPoint = previousPoint;
        previousPoint = currentPoint;
        currentPoint = new PointF(event.getX(), event.getY());
        drawLine(canvasBmp, path, paint, previousPoint, currentPoint);
        paintSize = 25;
        break;
    default:
        break;
    }

    invalidate();
    return true;// super.onTouchEvent(event);
}


@Override
protected void onDraw(Canvas canvas) {
    Log.v("pichan", "dasd");
    //canvas.drawBitmap(bmp, 0,0, null);
    //canvas.drawColor(Color.BLUE);
    //canvas.drawPath(path, paint); 
    canvas.drawBitmap(bmp, 0, 0, paintBm);

}





private void drawLine(Canvas canvas, Path path, Paint paint, PointF start, PointF end)
{
    PointF mid1 = midPoint(previousPoint, startPoint);
    PointF mid2 = midPoint(end, start);

    path.reset();
    paint.setStrokeWidth(paintSize);
    path.moveTo(mid1.x, mid1.y);
    path.quadTo(previousPoint.x, previousPoint.y, mid2.x, mid2.y);
    canvas.drawPath(path, paint);
    //canvas.
    //paintSize -= 1;
}

private PointF  midPoint(PointF p1, PointF p2)
{
    return new PointF((p1.x + p2.x) / 2.0f ,  (p1.y + p2.y) * 0.5f);
}

}
公共类TestView扩展了LinearLayout{
私有静态最终字符串TAG=“TestView”;
private PointF previousPoint;
专用点f起始点;
私有点f currentPoint;
专用静态最终浮动行程_宽度=5f;
专用静态最终浮动半冲程宽度=冲程宽度/2;
私有油漆=新油漆(油漆.防油漆别名标志);
私有油漆油漆BM=新油漆(油漆.防油漆别名标志);
私有位图bmp;
私人画布;
专用路径;
私人int paintSize=25;
公共测试视图(上下文、属性集属性){
超级(上下文,attrs);
此.setWillNotDraw(false);
paint.setAntiAlias(真);
绘制.设置样式(绘制.样式.笔划);
绘制.设置行程连接(绘制.连接.圆形);
油漆固定行程盖(油漆固定行程盖圆形);
油漆。设置行程宽度(行程宽度);
油漆。设置颜色(颜色。黑色);
//油漆。setAlpha(100);
paintBm.setantialas(真);
paintBm.setStyle(Paint.Style.STROKE);
paintBm.设置行程连接(Paint.Join.ROUND);
油漆固定行程盖(油漆固定行程盖圆形);
paintBm.设置行程宽度(行程宽度);
paintBm.setColor(颜色:黑色);
paintBm.setAlpha(100);
路径=新路径();
//paint.setPathEffect(新的CornerPathEffect(2));
}
公共测试视图(上下文){
超级(上下文);
//TODO自动生成的构造函数存根
paint.setAntiAlias(真);
绘制.设置样式(绘制.样式.笔划);
绘制.设置行程连接(绘制.连接.圆形);
油漆固定行程盖(油漆固定行程盖圆形);
油漆。设置行程宽度(行程宽度);
油漆。设置颜色(颜色。黑色);
路径=新路径();
//paint.setPathEffect(新的CornerPathEffect(2));
}
@凌驾
仅限受保护的空心布局(布尔值已更改、整数左侧、整数顶部、整数右侧、,
整数(底部){
//TODO自动生成的方法存根
超级。仅限布局(已更改、左、上、右、下);
如果(bmp==null){
bmp=Bitmap.createBitmap(右-左,下-上,Bitmap.Config.ARGB_8888);
canvasBmp=新画布(bmp);
}
}
@凌驾
公共布尔onTouchEvent(运动事件){
//印刷样品(事件);
开关(event.getAction()){
case MotionEvent.ACTION\u DOWN:
currentPoint=newpointf(event.getX(),event.getY());
前一点=当前点;
起始点=上一点;
path.reset();
打破
case MotionEvent.ACTION\u移动:
起始点=上一点;
前一点=当前点;
currentPoint=newpointf(event.getX(),event.getY());
int historySize=event.getHistorySize();
for(int i=0;i
经过一段时间的研究,我构建了一个SignView,让用户登录或绘图,结果将保存到一个图像文件中

感兴趣的任何人都可以在这里查看:


希望此自定义视图可以节省一些时间。

我使用您的逻辑绘制了平滑线,是的,它工作得很好,但在我的情况下,路径是使用可变宽度绘制的,为了实现我检测运动事件的压力,并根据用户直接触控笔施加的压力,我正在更改绘制笔划宽度,使用您的逻辑,一切正常,但有时绘制的路径不正确。你能检查一下我的代码有什么问题吗?这是个好主意,我现在很忙。我今晚去查一下。希望我能帮上忙好的……没问题。同时检查屏幕截图。这样你就能知道我的代码中到底出了什么问题。我检查了你的解决方案和你的问题。我认为用你的解决方案,这条线不可能是平坦的。因为事件(MotionEvent)之间的距离不同。如果你的手指快速移动,距离会变长,并且会反向移动。我们有三个点:p1,p2,p3。p1->p2=5和笔划大小之间的距离为10。距离p2->p3=10,笔划大小为20。=>线条不可能是平滑的。实际上,在我的例子中,基于不同的压力值,我正在为我的绘制对象设置strokeWidth值,在我的例子中,绘制的线条是平滑的,但是当压力值变化时,绘制线条,然后t