这段代码正常工作,我创建了Scratch图像视图,通过它我可以划伤图像视图以查看图像,但是当我重新打开应用程序或移动到上一个activity时,临时图像视图会自动填充划痕图案。一旦用户划伤图像视图以查看图像,当我重新打开应用程序或转移到上一个活动时,它不应再次填充。任何人都可以帮助我
<com.example.swapnanadendla.scratch.ScratchImageView
android:id="@+id/sample_image"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:background="@android:color/white"
android:src="@drawable/image" />
。
public class ScratchImageView extends ImageView{
public interface IRevealListener {
void onRevealed(ScratchImageView iv);
void onRevealPercentChangedListener(ScratchImageView siv, float percent);
}
public static final float STROKE_WIDTH = 12f;
private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;
/**
* Bitmap holding the scratch region.
*/
private Bitmap mScratchBitmap;
/**
* Drawable canvas area through which the scratchable area is drawn.
*/
private Canvas mCanvas;
/**
* Path holding the erasing path done by the user.
*/
private Path mErasePath;
/**
* Path to indicate where the user have touched.
*/
private Path mTouchPath;
/**
* Paint properties for drawing the scratch area.
*/
private Paint mBitmapPaint;
/**
* Paint properties for erasing the scratch region.
*/
private Paint mErasePaint;
/**
* Gradient paint properties that lies as a background for scratch region.
*/
private Paint mGradientBgPaint;
/**
* Sample Drawable bitmap having the scratch pattern.
*/
private BitmapDrawable mDrawable;
/**
* Listener object callback reference to send back the callback when the image has been revealed.
*/
private IRevealListener mRevealListener;
/**
* Reveal percent value.
*/
private float mRevealPercent;
/**
* Thread Count
*/
private int mThreadCount = 0;
public ScratchImageView(Context context) {
super(context);
init();
}
public ScratchImageView(Context context, AttributeSet set) {
super(context, set);
init();
}
public ScratchImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
/**
* Set the strokes width based on the parameter multiplier.
* @param multiplier can be 1,2,3 and so on to set the stroke width of the paint.
*/
public void setStrokeWidth(int multiplier) {
mErasePaint.setStrokeWidth(multiplier * STROKE_WIDTH);
}
/**
* Initialises the paint drawing elements.
*/
private void init() {
mTouchPath = new Path();
mErasePaint = new Paint();
mErasePaint.setAntiAlias(true);
mErasePaint.setDither(true);
mErasePaint.setColor(0xFFFF0000);
mErasePaint.setStyle(Paint.Style.STROKE);
mErasePaint.setStrokeJoin(Paint.Join.BEVEL);
mErasePaint.setStrokeCap(Paint.Cap.ROUND);
setStrokeWidth(6);
mGradientBgPaint = new Paint();
mErasePath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
Bitmap scratchBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_scratch_pattern);
mDrawable = new BitmapDrawable(getResources(), scratchBitmap);
mDrawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
setEraserMode();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mScratchBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mScratchBitmap);
Rect rect = new Rect(0, 0, mScratchBitmap.getWidth(), mScratchBitmap.getHeight());
mDrawable.setBounds(rect);
int startGradientColor = ContextCompat.getColor(getContext(), R.color.scratch_start_gradient);
int endGradientColor = ContextCompat.getColor(getContext(), R.color.scratch_end_gradient);
mGradientBgPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), startGradientColor, endGradientColor, Shader.TileMode.MIRROR));
mCanvas.drawRect(rect, mGradientBgPaint);
mDrawable.draw(mCanvas);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mScratchBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mErasePath, mErasePaint);
}
private void touch_start(float x, float y) {
mErasePath.reset();
mErasePath.moveTo(x, y);
mX = x;
mY = y;
}
/**
* clears the scratch area to reveal the hidden image.
*/
public void clear() {
int[] bounds = getImageBounds();
int left = bounds[0];
int top = bounds[1];
int right = bounds[2];
int bottom = bounds[3];
int width = right - left;
int height = bottom - top;
int centerX = left + width / 2;
int centerY = top + height / 2;
left = centerX - width / 2;
top = centerY - height / 2;
right = left + width;
bottom = top + height;
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
mCanvas.drawRect(left, top, right, bottom, paint);
checkRevealed();
invalidate();
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mErasePath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
drawPath();
}
mTouchPath.reset();
mTouchPath.addCircle(mX, mY, 30, Path.Direction.CW);
}
private void drawPath() {
mErasePath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mErasePath, mErasePaint);
// kill this so we don't double draw
mTouchPath.reset();
mErasePath.reset();
mErasePath.moveTo(mX, mY);
checkRevealed();
//reveal();
}
public void reveal() {
clear();
}
private void touch_up() {
drawPath();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
default:
break;
}
return true;
}
public int getColor() {
return mErasePaint.getColor();
}
public Paint getErasePaint() {
return mErasePaint;
}
public void setEraserMode() {
getErasePaint().setXfermode(new PorterDuffXfermode(
PorterDuff.Mode.CLEAR));
}
public void setRevealListener(IRevealListener listener) {
this.mRevealListener = listener;
}
public boolean isRevealed() {
return mRevealPercent == 1;
}
private void checkRevealed() {
if(! isRevealed() && mRevealListener != null) {
int[] bounds = getImageBounds();
int left = bounds[0];
int top = bounds[1];
int width = bounds[2] - left;
int height = bounds[3] - top;
// Do not create multiple calls to compare.
if(mThreadCount > 1) {
Log.d("Captcha", "Count greater than 1");
return;
}
mThreadCount++;
// new AsyncTask<Integer, Void, Float>() {
//
// @Override
// protected Float doInBackground(Integer... params) {
//
// try {
// int left = params[0];
// int top = params[1];
// int width = params[2];
// int height = params[3];
//
// Bitmap croppedBitmap = Bitmap.createBitmap(mScratchBitmap, left, top, width, height);
//
// return BitmapUtils.getTransparentPixelPercent(croppedBitmap);
// } finally {
// mThreadCount--;
// }
// }
//
// public void onPostExecute(Float percentRevealed) {
//
// // check if not revealed before.
// if( ! isRevealed()) {
//
// float oldValue = mRevealPercent;
// mRevealPercent = percentRevealed;
//
// if(oldValue != percentRevealed) {
// mRevealListener.onRevealPercentChangedListener(ScratchImageView.this, percentRevealed);
// }
//
// // if now revealed.
// if( isRevealed()) {
// mRevealListener.onRevealed(ScratchImageView.this);
// }
// }
// }
//
// }.execute(left, top, width, height);
}
}
public int[] getImageBounds() {
int paddingLeft = getPaddingLeft();
int paddingTop = getPaddingTop();
int paddingRight = getPaddingRight();
int paddingBottom = getPaddingBottom();
int vwidth = getWidth() - paddingLeft - paddingRight;
int vheight = getHeight() - paddingBottom - paddingTop;
int centerX = vwidth/2;
int centerY = vheight/2;
Drawable drawable = getDrawable();
Rect bounds = drawable.getBounds();
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
if(width <= 0) {
width = bounds.right - bounds.left;
}
if(height <= 0) {
height = bounds.bottom - bounds.top;
}
int left;
int top;
if(height > vheight) {
height = vheight;
}
if(width > vwidth) {
width = vwidth;
}
ScaleType scaleType = getScaleType();
switch (scaleType) {
case FIT_START:
left = paddingLeft;
top = centerY - height / 2;
break;
case FIT_END:
left = vwidth - paddingRight - width;
top = centerY - height / 2;
break;
case CENTER:
left = centerX - width / 2;
top = centerY - height / 2;
break;
default:
left = paddingLeft;
top = paddingTop;
width = vwidth;
height = vheight;
break;
}
return new int[] {left, top, left + width, top + height};
}
}
答案 0 :(得分:2)
你可以做的是将一个变量存储到firebase中,如isScratched = 1或0,如果它的1是因为用户没有抓它,如果用户抓它变量将为0然后在onStart你放一个监听器firebase数据库,如果监听器发现值为0,刮刮卡将不可用,我会在这里给你看一些片段
private DatabaseReference mDatabase; //First declare your database reference
然后在init()
或onCreate()
mDatabase = FirebaseDatabase.getInstance().getReference();
mDatabase.child("isScratched").setValue("1"); //here we create the isScratched and set it to 1 , meaning that the photo is not even scratched yet
现在,在划伤照片后,只需将该值设置为0
//After your scratch method or when the user finishes scratching the pick
mDatabase.child("isScratched").setValue("0");
现在在onStart()
或显示图片的活动中,只需附加一个监听器
mDatabase.child("isScratched").addSingleValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String getScratchedValue = datasnapshot.getValue(String.class);
Log.e("IsScratched : " ,""+getScratchedValue);
if(getScratchedValue.equals(0)){
//Your picture is already scratched, run the method that will show it scratched
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
System.out.println("Database Error: "+databaseError.getDetails());
}
});
希望有所帮助
快乐的编码!