我正在尝试使用演示开发手指画类型应用程序,除了擦除功能外,一切都很好。
我的主要活动是,
public class MainActivity extends Activity implements OnClickListener {
//custom drawing view
private DrawingView drawView;
//buttons
private ImageButton currPaint, drawBtn, eraseBtn, newBtn, saveBtn;
//sizes
private float smallBrush, mediumBrush, largeBrush;
//to save image
Bitmap saveImageBM;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//get drawing view
drawView = (DrawingView)findViewById(R.id.drawing);
//get the palette and first color button
LinearLayout paintLayout = (LinearLayout)findViewById(R.id.paint_colors);
currPaint = (ImageButton)paintLayout.getChildAt(0);
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
//sizes from dimensions
smallBrush = getResources().getInteger(R.integer.small_size);
mediumBrush = getResources().getInteger(R.integer.medium_size);
largeBrush = getResources().getInteger(R.integer.large_size);
//draw button
drawBtn = (ImageButton)findViewById(R.id.draw_btn);
drawBtn.setOnClickListener(this);
//set initial size
drawView.setBrushSize(smallBrush);
//erase button
eraseBtn = (ImageButton)findViewById(R.id.erase_btn);
eraseBtn.setOnClickListener(this);
//new button
newBtn = (ImageButton)findViewById(R.id.new_btn);
newBtn.setOnClickListener(this);
//save button
saveBtn = (ImageButton)findViewById(R.id.save_btn);
saveBtn.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
//user clicked paint
public void paintClicked(View view){
//use chosen color
//set erase false
drawView.setErase(false);
drawView.setBrushSize(drawView.getLastBrushSize());
if(view!=currPaint){
ImageButton imgView = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
//update ui
imgView.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currPaint.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currPaint=(ImageButton)view;
}
}
//called when draw_btn clicked
@Override
public void onClick(View view){
if(view.getId()==R.id.draw_btn){
//draw button clicked
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Brush size:");
brushDialog.setContentView(R.layout.brush_chooser);
//listen for clicks on size buttons
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
drawView.setErase(false);
drawView.setBrushSize(smallBrush);
drawView.setLastBrushSize(smallBrush);
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
drawView.setErase(false);
drawView.setBrushSize(mediumBrush);
drawView.setLastBrushSize(mediumBrush);
brushDialog.dismiss();
}
});
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
drawView.setErase(false);
drawView.setBrushSize(largeBrush);
drawView.setLastBrushSize(largeBrush);
brushDialog.dismiss();
}
});
//show and wait for user interaction
brushDialog.show();
}
else if(view.getId()==R.id.erase_btn){
//switch to erase - choose size
final Dialog brushDialog = new Dialog(this);
brushDialog.setTitle("Eraser size:");
brushDialog.setContentView(R.layout.brush_chooser);
//size buttons
ImageButton smallBtn = (ImageButton)brushDialog.findViewById(R.id.small_brush);
smallBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
drawView.setErase(true);
drawView.setBrushSize(smallBrush);
/*drawView.clearPoints();*/
brushDialog.dismiss();
}
});
ImageButton mediumBtn = (ImageButton)brushDialog.findViewById(R.id.medium_brush);
mediumBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
drawView.setErase(true);
drawView.setBrushSize(mediumBrush);
brushDialog.dismiss();
}
});
ImageButton largeBtn = (ImageButton)brushDialog.findViewById(R.id.large_brush);
largeBtn.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
drawView.setErase(true);
drawView.setBrushSize(largeBrush);
brushDialog.dismiss();
}
});
brushDialog.show();
}
else if(view.getId()==R.id.new_btn){
//new button
AlertDialog.Builder newDialog = new AlertDialog.Builder(this);
newDialog.setTitle("New drawing");
newDialog.setMessage("Start new drawing (you will lose the current drawing)?");
newDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
drawView.startNew();
dialog.dismiss();
}
});
newDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
newDialog.show();
}
else if(view.getId()==R.id.save_btn){
//save drawing
AlertDialog.Builder saveDialog = new AlertDialog.Builder(this);
saveDialog.setTitle("Save drawing");
saveDialog.setMessage("Save drawing to device Gallery?");
saveDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
//save drawing
drawView.setDrawingCacheEnabled(true);
//attempt to save
saveImageBM = drawView.getDrawingCache();
Log.i("image", " "+saveImageBM);
if (saveImageBM!=null) {
saveImage(saveImageBM);
}else{
Toast.makeText(getApplicationContext(), "Image is not saved", Toast.LENGTH_SHORT).show();
}
/*String imgSaved = MediaStore.Images.Media.insertImage(
getContentResolver(), drawView.getDrawingCache(),
UUID.randomUUID().toString()+".png", "drawing");*/
//feedback
/*if(imgSaved!=null){
Toast.makeText(getApplicationContext(), "Drawing saved to Gallery!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), "Oops! Image could not be saved.", Toast.LENGTH_SHORT).show();
}*/
drawView.destroyDrawingCache();
}
});
saveDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog, int which){
dialog.cancel();
}
});
saveDialog.show();
}
}
private void saveImage(Bitmap bitmap)
{
// save to folder in sd card
try
{
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "winoria");
if(!imagesFolder.exists())
imagesFolder.mkdirs();
StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
long bytesAvailable = (long)stat.getBlockSize() * (long)stat.getBlockCount();
long megAvailable = bytesAvailable / 1048576;
if(megAvailable>20)
{
String fileName=""+System.currentTimeMillis()+".jpg";
File output = new File(imagesFolder, fileName);
OutputStream fOut = new FileOutputStream(output);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
/*Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
File f = new File(Environment.getExternalStorageDirectory(), "winoria/"+fileName);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
sendBroadcast(mediaScanIntent); */
fOut.flush();
fOut.close();
Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_SHORT).show();
}
else
Toast.makeText(getApplicationContext(), "No enough space available", Toast.LENGTH_SHORT).show();
}
catch (FileNotFoundException e) {
//e.printStackTrace();
Toast.makeText(getApplicationContext(),"SlideShowFragement:"+e.toString(),Toast.LENGTH_LONG).show();
} catch (IOException e) {
Toast.makeText(getApplicationContext(),"SlideShowFragement:"+e.toString(),Toast.LENGTH_LONG).show();
//e.printStackTrace();
}
}
}
我的观点是,
public class DrawingView extends View {
//drawing path
private Path drawPath;
//drawing and canvas paint
private Paint drawPaint, canvasPaint;
//initial color
private int paintColor = 0xFF660000;
//canvas
private Canvas drawCanvas;
//canvas bitmap
private Bitmap canvasBitmap;
//brush sizes
private float brushSize, lastBrushSize;
//erase flag
private boolean erase=false;
public DrawingView(Context context, AttributeSet attrs){
super(context, attrs);
setupDrawing();
}
//setup drawing
private void setupDrawing(){
//prepare for drawing and setup paint stroke properties
brushSize = getResources().getInteger(R.integer.small_size);
lastBrushSize = brushSize;
drawPath = new Path();
drawPaint = new Paint();
//set initial color
drawPaint.setColor(paintColor);
//set initial path properties
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(brushSize);
drawPaint.setStyle(Paint.Style.STROKE);//we have two options Fill and STROKE
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
//will be called when the custom View is assigned a size:
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
//draw the view - will be called after touch event
@Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
canvas.drawPath(drawPath, drawPaint);
}
//register user touches as drawing action
@Override
public boolean onTouchEvent(MotionEvent event) {
//retrieve the X and Y positions of the user touch:
float touchX = event.getX();
float touchY = event.getY();
//respond to down, move and up events
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN://A pressed gesture has started, the motion contains the initial starting location.
drawPath.moveTo(touchX, touchY);//Set the beginning of the next contour to the point (x,y)
//extra code for erase
//mPaint.setStrokeWidth(25);
/*if(erase){
drawPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
drawCanvas.drawCircle(touchX, touchY, 10, drawPaint);
}
invalidate();*/
break;
case MotionEvent.ACTION_MOVE://A change has happened during a press gesture (between ACTION_DOWN and ACTION_UP).
drawPath.lineTo(touchX, touchY);//Add a line from the last point to the specified point (x,y)
//extra code for erase
/*if(erase){
drawCanvas.drawCircle(touchX, touchY, 20, drawPaint);
}
else{
drawPath.lineTo(touchX, touchY);
}invalidate();*/
break;
case MotionEvent.ACTION_UP://A pressed gesture has finished, the motion contains the final release location as well as any intermediate points since the last down or move event
drawPath.lineTo(touchX, touchY);
drawCanvas.drawPath(drawPath, drawPaint);//Draw the specified path using the specified paint.
//drawPath.rewind();
drawPath.reset();
break;
default:
return false;
}
//redraw
invalidate();
return true;
}
//update color
public void setColor(String newColor){
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
//set brush size
public void setBrushSize(float newSize){
float pixelAmount = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
newSize, getResources().getDisplayMetrics());
brushSize=pixelAmount;
drawPaint.setStrokeWidth(brushSize);
}
//get and set last brush size
public void setLastBrushSize(float lastSize){
lastBrushSize=lastSize;
}
public float getLastBrushSize(){
return lastBrushSize;
}
//set erase true or false
public void setErase(boolean isErase){
erase=isErase;
if(erase){
drawPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
}
else{
drawPaint.setXfermode(null);
}
}
//start new drawing
public void startNew(){
drawCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
invalidate();
}
}
问题部分是setErase函数,当我擦除它会显示黑色阴影时,我想删除它,所以请建议我如何解决这个问题。