Android 更改SignatureView的背景色
我在堆栈上找到了这段代码,它运行得很好。然而,有一个问题。虽然我可以设置它的背景色,但只要调用clearSignature()函数,颜色就会变为黑色 为什么会这样Android 更改SignatureView的背景色,android,android-canvas,Android,Android Canvas,我在堆栈上找到了这段代码,它运行得很好。然而,有一个问题。虽然我可以设置它的背景色,但只要调用clearSignature()函数,颜色就会变为黑色 为什么会这样 import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import and
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
/**
* A simple view to capture a path traced onto the screen. Initially intended to
* be used to captures signatures.
*
* @author Andrew Crichton
* @version 0.1
*/
public class SignatureView extends View
{
private Path mPath;
private Paint mPaint;
private Paint bgPaint = new Paint(Color.TRANSPARENT);
private Bitmap mBitmap;
private Canvas mCanvas;
private float curX, curY;
private static final int TOUCH_TOLERANCE = 4;
private static final int STROKE_WIDTH = 4;
boolean modified = false;
public SignatureView(Context context)
{
super(context);
init();
}
public SignatureView(Context context, AttributeSet attrs)
{
super(context, attrs);
init();
}
public SignatureView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
init();
}
private void init()
{
setFocusable(true);
mPath = new Path();
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(STROKE_WIDTH);
}
public void setSigColor(int color)
{
mPaint.setColor(color);
}
public void setSigColor(int a, int red, int green, int blue)
{
mPaint.setARGB(a, red, green, blue);
}
public boolean clearSignature()
{
if (mBitmap != null)
createFakeMotionEvents();
if (mCanvas != null)
{
mCanvas.drawColor(Color.BLACK);
mCanvas.drawPaint(bgPaint);
mPath.reset();
invalidate();
}
else
{
return false;
}
return true;
}
public Bitmap getImage()
{
return this.mBitmap;
}
public void setImage(Bitmap bitmap)
{
this.mBitmap = bitmap;
this.invalidate();
}
public boolean hasChanged()
{
return modified;
}
@Override protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight)
{
int bitmapWidth = mBitmap != null ? mBitmap.getWidth() : 0;
int bitmapHeight = mBitmap != null ? mBitmap.getWidth() : 0;
if (bitmapWidth >= width && bitmapHeight >= height)
return;
if (bitmapWidth < width)
bitmapWidth = width;
if (bitmapHeight < height)
bitmapHeight = height;
Bitmap newBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888);
Canvas newCanvas = new Canvas();
newCanvas.setBitmap(newBitmap);
if (mBitmap != null)
newCanvas.drawBitmap(mBitmap, 0, 0, null);
mBitmap = newBitmap;
mCanvas = newCanvas;
}
private void createFakeMotionEvents()
{
MotionEvent downEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_DOWN,
1f, 1f, 0);
MotionEvent upEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_UP, 1f,
1f, 0);
onTouchEvent(downEvent);
onTouchEvent(upEvent);
}
@Override protected void onDraw(Canvas canvas)
{
modified = true;
canvas.drawColor(Color.RED);
canvas.drawBitmap(mBitmap, 0, 0, mPaint);
canvas.drawPath(mPath, mPaint);
}
@Override public boolean onTouchEvent(MotionEvent event)
{
float x = event.getX();
float y = event.getY();
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touchDown(x, y);
break;
case MotionEvent.ACTION_MOVE:
touchMove(x, y);
break;
case MotionEvent.ACTION_UP:
touchUp();
break;
}
invalidate();
return true;
}
/**
* ---------------------------------------------------------- Private
* methods ---------------------------------------------------------
*/
private void touchDown(float x, float y)
{
mPath.reset();
mPath.moveTo(x, y);
curX = x;
curY = y;
}
private void touchMove(float x, float y)
{
float dx = Math.abs(x - curX);
float dy = Math.abs(y - curY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE)
{
mPath.quadTo(curX, curY, (x + curX) / 2, (y + curY) / 2);
curX = x;
curY = y;
}
}
private void touchUp()
{
mPath.lineTo(curX, curY);
if (mCanvas == null)
{
mCanvas = new Canvas();
mCanvas.setBitmap(mBitmap);
}
mCanvas.drawPath(mPath, mPaint);
mPath.reset();
}
}
导入android.content.Context;
导入android.graphics.Bitmap;
导入android.graphics.Canvas;
导入android.graphics.Color;
导入android.graphics.Paint;
导入android.graphics.Path;
导入android.os.SystemClock;
导入android.util.AttributeSet;
导入android.view.MotionEvent;
导入android.view.view;
/**
*一个简单的视图,用于捕获屏幕上跟踪的路径。最初打算
*用于捕获签名。
*
*@作者安德鲁·克莱顿
*@version 0.1
*/
公共类SignatureView扩展视图
{
专用路径mPath;
私人油漆;
私人油漆bgPaint=新油漆(颜色:透明);
私有位图mBitmap;
私人帆布mCanvas;
私人浮动curX,curY;
专用静态最终内部接触公差=4;
专用静态最终int笔划_宽度=4;
布尔修改=假;
公共签名视图(上下文)
{
超级(上下文);
init();
}
public SignatureView(上下文、属性集属性)
{
超级(上下文,attrs);
init();
}
public SignatureView(上下文、属性集属性、int-defStyle)
{
超级(上下文、属性、定义样式);
init();
}
私有void init()
{
设置聚焦(真);
mPath=新路径();
mPaint=新绘制(Paint.ANTI\u ALIAS_标志);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(油漆、样式、笔划);
mPaint.设置行程宽度(行程宽度);
}
公共void setSigColor(内部颜色)
{
mPaint.setColor(颜色);
}
公共无效设置SigColor(内部a、内部红色、内部绿色、内部蓝色)
{
mPaint.setARGB(a、红色、绿色、蓝色);
}
公共签名()
{
如果(mBitmap!=null)
createFakeMotionEvents();
如果(mCanvas!=null)
{
mCanvas.drawColor(颜色:黑色);
mCanvas.drawPaint(bgPaint);
mPath.reset();
使无效();
}
其他的
{
返回false;
}
返回true;
}
公共位图getImage()
{
返回此.mBitmap;
}
公共void setImage(位图)
{
this.mBitmap=位图;
这个。使无效();
}
公共布尔值已更改()
{
修改返回值;
}
@在尺寸更改时替代受保护的空心(int-width、int-height、int-oldWidth、int-oldHeight)
{
int bitmapWidth=mBitmap!=null?mBitmap.getWidth():0;
int bitmapHeight=mBitmap!=null?mBitmap.getWidth():0;
如果(位图宽度>=宽度和位图高度>=高度)
返回;
if(位图宽度<宽度)
位图宽度=宽度;
if(位图高度<高度)
位图高度=高度;
位图newBitmap=Bitmap.createBitmap(位图宽度、位图高度、Bitmap.Config.ARGB_8888);
Canvas newCanvas=新画布();
newCanvas.setBitmap(newBitmap);
如果(mBitmap!=null)
drawBitmap(mBitmap,0,0,null);
mBitmap=newBitmap;
mCanvas=newCanvas;
}
私有void createFakeMotionEvents()
{
MotionEvent downEvent=MotionEvent.Acquire(SystemClock.uptimeMillis(),SystemClock.uptimeMillis()+100,MotionEvent.ACTION_DOWN,
1f、1f、0);
MotionEvent upEvent=MotionEvent.Acquire(SystemClock.uptimeMillis(),SystemClock.uptimeMillis()+100,MotionEvent.ACTION\u UP,1f,
1f,0);
onTouchEvent(downEvent);
onTouchEvent(upEvent);
}
@覆盖受保护的void onDraw(画布)
{
修改=真;
画布。drawColor(颜色。红色);
drawBitmap(mBitmap,0,0,mPaint);
画布绘制路径(mPath,mPaint);
}
@重写公共布尔onTouchEvent(MotionEvent事件)
{
float x=event.getX();
float y=event.getY();
开关(event.getAction())
{
case MotionEvent.ACTION\u DOWN:
接地(x,y);
打破
case MotionEvent.ACTION\u移动:
touchMove(x,y);
打破
case MotionEvent.ACTION\u UP:
修补();
打破
}
使无效();
返回true;
}
/**
*第三十四天——私人
*方法---------------------------------------------------------
*/
专用空位着陆(浮动x、浮动y)
{
mPath.reset();
移动到(x,y)的速度;
curX=x;
curY=y;
}
私有无效触摸移动(浮动x、浮动y)
{
float dx=Math.abs(x-curX);
float dy=Math.abs(y-curY);
如果(dx>=接触公差| | dy>=接触公差)
{
mPath.quadTo(curX,curY,(x+curX)/2,(y+curY)/2);
curX=x;
curY=y;
}
}
私人修补
{
mPath.lineTo(curX,curY);
如果(mCanvas==null)
{
mCanvas=新画布();
mCanvas.setBitmap(mBitmap);
}
mCanvas.drawPath(mPath,mPaint);
mPath.reset();
}
}
我已经更新了原始SignatureView代码,现在它支持自定义签名背景色。此颜色与视图的背景色不同
setSigBackgroundColor()
我还做了一些其他的优化,风险自负,因为这是最低限度的测试
优化的小列表:
- 更好的位图回收等
- 运动事件的循环利用
- 添加了签名背景颜色集方法
- 优化
- 改变了setImage方法,尽管对u仍然不是很安全
import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.os.SystemClock; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * A simple view to capture a path traced onto the screen. Initially intended to * be used to captures signatures. * * @author Andrew Crichton * @version 0.1.1 * * Modified by Rolf Smit * -Recycle bitmaps * -Recycle MotionEvents * -Signature Background color changes * -Optimizations * -Changed setImage method, although still unsafe to use! */ public class SignatureView extends View { private Path mPath; private Paint mPaint; private Bitmap mBitmap; private Canvas mCanvas; private int sigBackgroundColor = Color.TRANSPARENT; private float curX, curY; private static final int TOUCH_TOLERANCE = 4; private static final int STROKE_WIDTH = 4; boolean modified = false; public SignatureView(Context context) { super(context); init(); } public SignatureView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public SignatureView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { setFocusable(true); mPath = new Path(); mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setColor(Color.WHITE); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeWidth(STROKE_WIDTH); } public void setSigColor(int color) { mPaint.setColor(color); } public void setSigColor(int alpha, int red, int green, int blue) { mPaint.setARGB(alpha, red, green, blue); } public void setSigBackgroundColor(int color){ sigBackgroundColor = color; } public void setSigBackgroundColor(int alpha, int red, int green, int blue){ sigBackgroundColor = Color.argb(alpha, red, green, blue); } public boolean clearSignature() { if (mBitmap != null) { createFakeMotionEvents(); } if (mCanvas != null) { mCanvas.drawColor(sigBackgroundColor); mPath.reset(); invalidate(); } else { return false; } return true; } public Bitmap getImage() { return Bitmap.createBitmap(mBitmap); } public void setImage(Bitmap bitmap){ this.mBitmap = bitmap; if(mCanvas != null){ mCanvas.setBitmap(mBitmap); } } public boolean hasChanged() { return modified; } @Override protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) { int bitmapWidth = mBitmap != null ? mBitmap.getWidth() : 0; int bitmapHeight = mBitmap != null ? mBitmap.getWidth() : 0; if (bitmapWidth >= width && bitmapHeight >= height) { return; } if (bitmapWidth < width) { bitmapWidth = width; } if (bitmapHeight < height) { bitmapHeight = height; } Bitmap newBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); Canvas newCanvas = new Canvas(); newCanvas.setBitmap(newBitmap); mCanvas = newCanvas; if (mBitmap != null) { newCanvas.drawBitmap(mBitmap, 0, 0, null); mBitmap.recycle(); } else { newCanvas.drawColor(sigBackgroundColor); } mBitmap = newBitmap; } private void createFakeMotionEvents() { MotionEvent downEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_DOWN, 1f, 1f, 0); MotionEvent upEvent = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis() + 100, MotionEvent.ACTION_UP, 1f, 1f, 0); onTouchEvent(downEvent); onTouchEvent(upEvent); downEvent.recycle(); upEvent.recycle(); } @Override protected void onDraw(Canvas canvas) { modified = true; canvas.drawBitmap(mBitmap, 0, 0, mPaint); canvas.drawPath(mPath, mPaint); } @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touchDown(x, y); break; case MotionEvent.ACTION_MOVE: touchMove(x, y); break; case MotionEvent.ACTION_UP: touchUp(); break; } invalidate(); return true; } private void touchDown(float x, float y) { mPath.reset(); mPath.moveTo(x, y); curX = x; curY = y; } private void touchMove(float x, float y) { float dx = Math.abs(x - curX); float dy = Math.abs(y - curY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(curX, curY, (x + curX) / 2, (y + curY) / 2); curX = x; curY = y; } } private void touchUp() { mPath.lineTo(curX, curY); if (mCanvas == null) { mCanvas = new Canvas(); mCanvas.setBitmap(mBitmap); } mCanvas.drawPath(mPath, mPaint); mPath.reset(); } }