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