Android 更改SignatureView的背景色

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

我在堆栈上找到了这段代码,它运行得很好。然而,有一个问题。虽然我可以设置它的背景色,但只要调用clearSignature()函数,颜色就会变为黑色

为什么会这样

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();
        }
    }