I draw using my finger some signatures using this fragment, it works fine but when I try to save the bitmap, I try this function Bitmap bitmap = view.getDrawingCache(); but it's always Null , so my question is how to get the real file bitmap to use it after !
this is my code :
public class FingerDrawFragment extends DialogFragment
{
private RelativeLayout relativeLayout;
private Paint paint;
private View view;
private Path path2;
private Bitmap bitmap;
private Canvas canvas;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.draw_fragment, container, false);
Bundle b = getArguments();
if(b != null)
{
int id = b.getInt("id");
Boolean isInfraction = b.getBoolean("infraction");
if(isInfraction)
infraction = realm.where(Infraction.class).equalTo("id",id).findFirst();
}
view = new SketchSheetView(getActivity());
paint = new Paint();
path2 = new Path();
paint.setDither(true);
paint.setColor(getResources().getColor(R.color.TealDark));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(2);
((RelativeLayout) v.findViewById(R.id.body)).addView(view );
((TextView)v.findViewById(R.id.topBarTitle)).setText("Signature");
v.findViewById(R.id.delete_draw).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
path2.reset();
}
});
v.findViewById(R.id.save_draw).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
AlertDialog.Builder editalert = new AlertDialog.Builder(getActivity());
editalert.setTitle("Please Enter the name with which you want to Save");
final EditText input = new EditText(getActivity());
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT);
input.setLayoutParams(lp);
editalert.setView(input);
editalert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String name= input.getText().toString();
Bitmap bitmap = view.getDrawingCache();
String root = Utils.getFirstWritableDirectory().toString();
File file = new File(root + "/.SMS_Images/"+name+".png");
try
{
if(!file.exists())
{
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
view.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}finally
{
view.setDrawingCacheEnabled(false);
}
}
});
editalert.show();
}
});
return v;
}
class SketchSheetView extends View {
public SketchSheetView(Context context) {
super(context);
bitmap = Bitmap.createBitmap(820, 480, Bitmap.Config.ARGB_4444);
canvas = new Canvas(bitmap);
this.setBackgroundColor(Color.WHITE);
}
private ArrayList<DrawingClass> DrawingClassArrayList = new ArrayList<DrawingClass>();
#Override
public boolean onTouchEvent(MotionEvent event) {
DrawingClass pathWithPaint = new DrawingClass();
canvas.drawPath(path2, paint);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
path2.moveTo(event.getX(), event.getY());
path2.lineTo(event.getX(), event.getY());
}
else if (event.getAction() == MotionEvent.ACTION_MOVE) {
path2.lineTo(event.getX(), event.getY());
pathWithPaint.setPath(path2);
pathWithPaint.setPaint(paint);
DrawingClassArrayList.add(pathWithPaint);
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (DrawingClassArrayList.size() > 0) {
canvas.drawPath(
DrawingClassArrayList.get(DrawingClassArrayList.size() - 1).getPath(),
DrawingClassArrayList.get(DrawingClassArrayList.size() - 1).getPaint());
}
}
}
public class DrawingClass {
Path DrawingClassPath;
Paint DrawingClassPaint;
public Path getPath() {
return DrawingClassPath;
}
public void setPath(Path path) {
this.DrawingClassPath = path;
}
public Paint getPaint() {
return DrawingClassPaint;
}
public void setPaint(Paint paint) {
this.DrawingClassPaint = paint;
}
}
}
add
view.setDrawingCacheEnabled(true);
before
Bitmap bitmap = view.getDrawingCache();
Related
Canvas Painting is not reset when Click ,It is reset when I am drawing again on canvas after click the clear button.............................................................................................................................................................................................................................................................................................................................................................................
HERE IS MY CODE
public class Practice extends FragmentActivity {
private RelativeLayout relativeLayout;
private Paint paint;
ImageView back;
private View view;
private Path path2;
private Bitmap bitmap;
private Canvas canvas;
private Button button;
public int width, height;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_practice);
back = findViewById(R.id.back);
relativeLayout = (RelativeLayout) findViewById(R.id.relativelayout1);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
button = (Button) findViewById(R.id.button);
view = new SketchSheetView(Practice.this);
paint = new Paint();
path2 = new Path();
relativeLayout.addView(view, new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
paint.setDither(true);
paint.setColor(Color.parseColor("#FFFFFF"));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.MITER);
paint.setStrokeCap(Paint.Cap.BUTT);
paint.setStrokeWidth(5);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
path2.reset();
}
});
}
class SketchSheetView extends View {
public SketchSheetView(Context context) {
super(context);
bitmap = Bitmap.createBitmap(100, 200, Bitmap.Config.ARGB_4444);
canvas = new Canvas(bitmap);
this.setBackground(getResources().getDrawable(R.drawable.ic_brush_black_24dp));
}
private ArrayList<DrawingClass> DrawingClassArrayList = new ArrayList<DrawingClass>();
#Override
public boolean onTouchEvent(MotionEvent event) {
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
DrawingClass pathWithPaint = new DrawingClass();
canvas.drawPath(path2, paint);
if (event.getAction() == MotionEvent.ACTION_DOWN) {
this.setBackground(null);
vibrator.vibrate(500);
path2.moveTo(event.getX(), event.getY());
path2.lineTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
this.setBackground(null);
path2.lineTo(event.getX(), event.getY());
vibrator.vibrate(500);
pathWithPaint.setPath(path2);
pathWithPaint.setPaint(paint);
DrawingClassArrayList.add(pathWithPaint);
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (DrawingClassArrayList.size() > 0) {
canvas.drawPath(
DrawingClassArrayList.get(DrawingClassArrayList.size() - 1).getPath(),
DrawingClassArrayList.get(DrawingClassArrayList.size() - 1).getPaint()
);
}
}
}
public class DrawingClass {
Path DrawingClassPath;
Paint DrawingClassPaint;
public Path getPath() {
return DrawingClassPath;
}
public void setPath(Path path) {
this.DrawingClassPath = path;
}
public Paint getPaint() {
return DrawingClassPaint;
}
public void setPaint(Paint paint) {
this.DrawingClassPaint = paint;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
I have created a simple drawing app, in which i am using a seek bar to get stroke width. But as soon as i change the stroke width, the width of complete drawing changes. Same happens when i change the pen color. How to individually assign stroke attributes to each path?
I have tried many answers but could not get the correct result.
I have tried storing the path and the respective paint associated with it and then drawing it. but that too didn't work.
public class MainActivity extends AppCompatActivity {
View mView;
private Paint mPaint;
SeekBar mSeekbar;
int penColor = Color.BLACK;
int bgColor = Color.WHITE;
int StrokeWidth = 12;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = (LinearLayout) findViewById(R.id.myDrawing);
mView = new DrawingView(this);
mSeekbar = (SeekBar) findViewById(R.id.seek);
mSeekbar.getProgressDrawable().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
mSeekbar.getThumb().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
layout.addView(mView, new ActionBar.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT));
((DrawingView) mView).init();
penSize();
}
public void penSize() {
mSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
((DrawingView) mView).changePenSize(StrokeWidth);
StrokeWidth = i;
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
((DrawingView) mView).changePenSize(StrokeWidth);
}
});
}
class DrawingView extends View {
private Path path;
private Bitmap mBitmap;
private Canvas mCanvas;
public DrawingView(Context context) {
super(context);
path = new Path();
mBitmap = Bitmap.createBitmap(820, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
this.setBackgroundColor(bgColor);
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(penColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(StrokeWidth);
}
public void changePenSize(int size) {
StrokeWidth = size;
mPaint.setStrokeWidth(StrokeWidth);
invalidate();
}
public void init() {
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(penColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(StrokeWidth);
}
public void setBGColor(int color) {
bgColor = color;
this.setBackgroundColor(bgColor);
invalidate();
}
public void ClearPath() {
path.reset();
bgColor = Color.WHITE;
penColor = Color.BLACK;
init();
invalidate();
}
public void changePenColor() {
mPaint.setColor(penColor);
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
path.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
mCanvas.drawPath(path, mPaint);
break;
default:
return false;
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, mPaint);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
File myDir = new File(Environment.getExternalStorageDirectory(),
"Drawings");
myDir.mkdirs();
Date now = new Date();
String fname = "image" + now.getDate() + now.getSeconds() + ".jpg";
File file = new File(myDir, fname);
//noinspection SimplifiableIfStatement
if (id == R.id.clear) {
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setTitle("Do you really want to clear ?\nYou can save before clearing.");
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
((DrawingView) mView).ClearPath();
Toast.makeText(MainActivity.this, "Done", Toast.LENGTH_SHORT).show();
}
});
alert.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alert.show();
return true;
} else if (id == R.id.bgColor) {
bgColor();
} else if (id == R.id.penColor) {
penColor();
} else if (id == R.id.screenshot) {
takeScreenshot();
return true;
}
return super.onOptionsItemSelected(item);
}
private void penColor() {
AmbilWarnaDialog dialog = new AmbilWarnaDialog(MainActivity.this, Color.BLACK, new AmbilWarnaDialog.OnAmbilWarnaListener() {
#Override
public void onOk(AmbilWarnaDialog dialog, int color) {
penColor = color;
((DrawingView) mView).changePenColor();
}
#Override
public void onCancel(AmbilWarnaDialog dialog) {
}
});
dialog.show();
}
private void bgColor() {
AmbilWarnaDialog dialog = new AmbilWarnaDialog(MainActivity.this, Color.BLACK, new AmbilWarnaDialog.OnAmbilWarnaListener() {
#Override
public void onOk(AmbilWarnaDialog dialog, int color) {
bgColor = color;
((DrawingView) mView).setBGColor(bgColor);
}
#Override
public void onCancel(AmbilWarnaDialog dialog) {
}
});
dialog.show();
}
private void takeScreenshot() {
mView.setDrawingCacheEnabled(true);
String filename= UUID.randomUUID().toString() + ".png";
String imgSaved = MediaStore.Images.Media.insertImage(
getContentResolver(), mView.getDrawingCache(),
filename, "drawing");
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();
}
mView.destroyDrawingCache();
}
}
class DrawingView extends View {
ArrayList<DrawingPath> paths;
private DrawingPath drawingPath;
private Bitmap mBitmap;
private Canvas mCanvas;
public DrawingView(Context context) {
super(context);
paths = new ArrayList<>();
mBitmap = Bitmap.createBitmap(820, 480, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
this.setBackgroundColor(bgColor);
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(penColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(StrokeWidth);
}
public void changePenSize(int size) {
StrokeWidth = size;
mPaint.setStrokeWidth(StrokeWidth);
}
public void init() {
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(penColor);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(StrokeWidth);
}
public void setBGColor(int color) {
bgColor = color;
this.setBackgroundColor(bgColor);
invalidate();
}
public void ClearPath() {
paths.clear();
bgColor = Color.WHITE;
penColor = Color.BLACK;
init();
invalidate();
}
public void changePenColor() {
mPaint.setColor(penColor);
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawingPath = new DrawingPath(mPaint.getStrokeWidth());
paths.add(drawingPath);
drawingPath.path.moveTo(touchX, touchY);
break;
case MotionEvent.ACTION_MOVE:
drawingPath.path.lineTo(touchX, touchY);
break;
case MotionEvent.ACTION_UP:
mCanvas.drawPath(drawingPath.path, mPaint);
break;
default:
return false;
}
invalidate();
return true;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (DrawingPath drawingPath : paths) {
mPaint.setStrokeWidth(drawingPath.strokeWidth);
canvas.drawPath(drawingPath.path, mPaint);
}
}
}
class DrawingPath {
Path path;
float strokeWidth;
DrawingPath(float strokeWidth) {
path = new Path();
this.strokeWidth = strokeWidth;
}
}
I hope this will help. You can other properties like color,style, etc to DrawingPath model.
I am done creating different brush effect in for canvas. When i change the brush then previously drawn paint is change to that brush effect. So what i do for that? If any guidance then please provide me.
Below is my DrawingView class.
public class DrawingView extends View
{
private final Paint mPaintSrcIn = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
private final Paint mPaintDstIn = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
public Paint mPaintColor = new Paint(Paint.ANTI_ALIAS_FLAG);
public Paint mPaintColor1 = new Paint(Paint.ANTI_ALIAS_FLAG);
// public final Paint mPaintColor2 = new Paint(Paint.ANTI_ALIAS_FLAG);
// public final Paint mPaintColor3 = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mPaintEraser = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Matrix mMatrix = new Matrix();
private final Canvas mLayerCanvas = new Canvas();
private Bitmap mInnerShape;
private Bitmap mOuterShape;
private Bitmap mLayerBitmap;
private Color mInnerColor,mOuterColor;
PlayActivity playActivity = new PlayActivity();
private int mFlag;
private int paintAlpha = 255;
private int paintColor = 0xFFFF0000;
private ArrayList<DrawOp> mDrawOps = new ArrayList<DrawOp>();
private ArrayList<DrawOp> mDrawOps1 = new ArrayList<DrawOp>();
private DrawOp mCurrentOp = new DrawOp();
private DrawOp mPreviousOp = new DrawOp();
private ArrayList<DrawOp> mUndoneOps = new ArrayList<DrawOp>();
public DrawingView(Context context)
{
this(context, null, 0);
}
public DrawingView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public DrawingView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
mPaintSrcIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
mPaintDstIn.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintEraser.set(mPaintColor);
mPaintEraser.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
mPaintEraser.setMaskFilter(new BlurMaskFilter(getResources()
.getDisplayMetrics().density * 4, BlurMaskFilter.Blur.NORMAL));
}
public void setShape(int inner, int outer)
{
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ALPHA_8;
setShape(BitmapFactory.decodeResource(getResources(), inner, options),
BitmapFactory.decodeResource(getResources(), outer, options));
}
public void setShape(Bitmap inner, Bitmap outer)
{
mInnerShape = inner;
mOuterShape = outer;
requestLayout();
invalidate();
}
public void setDrawingColor(int color)
{
mCurrentOp.reset();
mCurrentOp.type = DrawOp.Type.PAINT;
mCurrentOp.color = color;
mPreviousOp.reset();
mPreviousOp.type = DrawOp.Type.PAINT;
mPreviousOp.color = color;
}
public void setDrawingStroke(int stroke)
{
mCurrentOp.reset();
mCurrentOp.type = DrawOp.Type.PAINT;
mCurrentOp.stroke = stroke;
}
public void enableEraser()
{
mCurrentOp.reset();
mCurrentOp.type = DrawOp.Type.ERASE;
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
mLayerBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mLayerCanvas.setBitmap(mLayerBitmap);
if(mOuterShape != null){
int dx = (w - mOuterShape.getWidth()) / 2;
int dy = (h - mOuterShape.getHeight()) / 2;
mMatrix.setTranslate(dx, dy);
}
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
if(isInEditMode()){
return;
}
// NOTE: Without extra bitmap or layer.. but HW Acceleration does not support setMaskFilter which means
// eraser has strong edges whilst drawing.
// #see http://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
System.out.println("Flag before if "+mFlag);
if(mFlag==0){
System.out.println("Flag = 0 "+mFlag);
// Clear software canvas
// mPaintColor1 = mPaintColor;
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintColor.setMaskFilter(null);
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for (DrawOp op : mDrawOps) {
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
System.out.println("Drawing Flag : " + mFlag);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn);
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
}else if(mFlag==1){
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintColor.setMaskFilter(null);
// Clear software canvas
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for(DrawOp op : mDrawOps){
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn);
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
canvas.save();
}
else if(mFlag==2){
System.out.println("Flag = 2 "+mFlag);
// mPaintColor1 = mPaintColor;
/* Blur Effect for creating more effect then change following properties
BlurMaskFilter.Blur.INNER,BlurMaskFilter.Blur.NORMAL,BlurMaskFilter.Blur.OUTER
BlurMaskFilter.Blur.SOLID*/
// Code Here
BlurMaskFilter mBlur = new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL);
mPaintColor.setMaskFilter(mBlur);
// Clear software canvas
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for (DrawOp op : mDrawOps) {
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn); /*mPaintDstIn*/
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
canvas.save();
}
else if(mFlag==3){
mPaintColor.setStyle(Paint.Style.STROKE);
mPaintColor.setStrokeJoin(Paint.Join.ROUND);
mPaintColor.setStrokeCap(Paint.Cap.ROUND);
mPaintColor.setMaskFilter(null);
mPaintColor.setMaskFilter(new EmbossMaskFilter(new float[] { 1, 1, 1 },0.4f, 10, 8.2f));
// Clear software canvas
mLayerCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
// Draw picture from ops
for (DrawOp op : mDrawOps) {
drawOp(mLayerCanvas, op);
}
drawOp(mLayerCanvas, mCurrentOp);
// Mask the drawing to the inner surface area of the shape
mLayerCanvas.drawBitmap(mInnerShape, mMatrix, mPaintDstIn);
// Draw orignal shape to view
canvas.drawBitmap(mOuterShape, mMatrix, null);
// Draw masked image to view
canvas.drawBitmap(mLayerBitmap, 0, 0, null);
canvas.save();
}
}
private void drawOp(Canvas canvas, DrawOp op)
{
if(op.path.isEmpty()){
return;
}
final Paint paint;
if(op.type == DrawOp.Type.PAINT){
paint = mPaintColor;
paint.setColor(op.color);
paint.setStrokeWidth(op.stroke);
}else{
paint = mPaintEraser;
paint.setStrokeWidth(op.stroke);
}
mLayerCanvas.drawPath(op.path, paint);
}
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouchEvent(MotionEvent event)
{
final float x = event.getX();
final float y = event.getY();
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
mUndoneOps.clear();
mCurrentOp.path.moveTo(x, y);
break;
case MotionEvent.ACTION_MOVE:
for(int i = 0; i < event.getHistorySize(); i++){
mCurrentOp.path.lineTo(event.getHistoricalX(i), event.getHistoricalY(i));
}
mCurrentOp.path.lineTo(x, y);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mCurrentOp.path.lineTo(x, y);
mDrawOps.add(new DrawOp(mCurrentOp));
mCurrentOp.path.reset();
break;
}
invalidate();
return true;
}
private static class DrawOp
{
public final Path path = new Path();
public Type type;
public int color;
public int stroke;
public DrawOp()
{
//
}
public void reset()
{
this.path.reset();
}
public DrawOp(DrawOp op)
{
this.path.set(op.path);
this.type = op.type;
this.color = op.color;
this.stroke = op.stroke;
}
public static enum Type
{
PAINT, ERASE;
}
}
public void setFlag(int flag) {
System.out.println("Before Set mFlag " + mFlag);
this.mFlag = flag;
System.out.println("After Set mFlag " + mFlag);
}
}
This is my Activity Class for changing brush effect using button click
public class PlayActivity extends Activity{
private DrawingView mDrawingView;
private ViewGroup mBrushPanel;
private ViewGroup mBrushColors;
private SeekBar mBrushStroke;
private ViewGroup brush_panel_pencil;
private ViewGroup brush_colors_pencil;
private SeekBar brush_stroke_pencil;
String imagName ="";
private static String APP_ID = "788092211287311";
// Instance of Facebook Class
private Facebook facebook;
private AsyncFacebookRunner mAsyncRunner;
String FILENAME = "AndroidSSO_data";
private SharedPreferences mPrefs;
public boolean flag = false;
String name="";
File file = null;
FileOutputStream fOut = null;
// see:
// http://stackoverflow.com/questions/25758294/how-to-fill-different-color-on-same-area-of-imageview-color-over-another-color/
static int[] COLORS = { Color.rgb(255, 51, 255), // DARK PINK
Color.rgb(255, 230, 102), // LIGHT YELLOW
Color.rgb(148, 66, 50), // DARK MAROON
Color.rgb(186, 123, 68), // LIGHT MAROON
Color.rgb(252, 20, 20), // RED
Color.rgb(102, 255, 255), // LIGHT BLUE
Color.rgb(70, 78, 202), // DARK BLUE
Color.rgb(190, 255, 91), // LIGHT GREEN
Color.rgb(15, 230, 0), // DARK GREEN
Color.rgb(123, 0, 230), // JAMBLI
Color.rgb(255, 187, 50), // ORANGE
Color.rgb(7, 5, 0), // BLACK
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setBackgroundDrawable(
Utils.createCheckerBoard(getResources(), 16));
setContentView(R.layout.activity_play);
mDrawingView = (DrawingView) findViewById(R.id.drawing_view);
// mDrawingView.setShape(R.drawable.img_a_inner, R.drawable.img_a);
mDrawingView.setShape(R.drawable.inner, R.drawable.outer);
mDrawingView.setDrawingColor(getResources().getColor(R.color.ab_color));
mDrawingView.setFlag(0);
mBrushPanel = (ViewGroup) findViewById(R.id.brush_panel);
mBrushColors = (ViewGroup) findViewById(R.id.brush_colors);
mBrushStroke = (SeekBar) findViewById(R.id.brush_stroke);
mBrushStroke
.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
#Override
public void onProgressChanged(SeekBar seekBar,
int progress, boolean fromUser) {
mDrawingView.setDrawingStroke(progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
});
mBrushStroke.setProgress(30);
mBrushPanel.getViewTreeObserver().addOnPreDrawListener(
new ViewTreeObserver.OnPreDrawListener() {
#Override
public boolean onPreDraw() {
mBrushPanel.getViewTreeObserver()
.removeOnPreDrawListener(this);
mBrushPanel
.setTranslationY(isLandscape() ? -mBrushPanel
.getHeight() : mBrushPanel.getHeight());
return false;
}
});
createBrushPanelContent();
}
#SuppressWarnings("null")
private void createBrushPanelContent() {
TableRow tableRow = null;
final int rowLimit = isLandscape() ? 16 : 8;
for (int i = 0; i < COLORS.length; i++) {
if ((i % rowLimit) == 0) {
tableRow = new TableRow(this);
mBrushColors.addView(tableRow, new TableLayout.LayoutParams(
WRAP_CONTENT, WRAP_CONTENT));
}
tableRow.addView(createToolButton(tableRow,
R.drawable.ic_paint_splot, i));
}
/*tableRow.addView(createToolButton1(tableRow, R.drawable.ic_paint_splot,
1));*/
}
private void showBrushPanel() {
mBrushPanel.animate().translationY(0).start();
}
private void hideBrushPanel() {
mBrushPanel
.animate()
.translationY(
isLandscape() ? -mBrushPanel.getHeight() : mBrushPanel
.getHeight()).start();
}
private boolean isLandscape() {
return getResources().getBoolean(R.bool.is_landscape);
}
private ImageButton createToolButton(ViewGroup parent, int drawableResId,
int index) {
ImageButton button = (ImageButton) getLayoutInflater().inflate(
R.layout.button_paint_spot, parent, false);
button.setImageResource(drawableResId);
button.setOnClickListener(mButtonClick);
if (index != -1) {
button.setTag(Integer.valueOf(index));
button.setColorFilter(COLORS[index]);
}
return button;
}
/* private Button createToolButton1(ViewGroup parent, int drawableResId,
int index) {
Button buttonShare = (Button) getLayoutInflater().inflate(
R.layout.button, parent, false);
buttonShare.setOnClickListener(mButtonShare);
return buttonShare;
}
};*/
private View.OnClickListener mButtonClick = new View.OnClickListener() {
#Override
public void onClick(View v) {
// code for set the shadow color
// mDrawingView.mPaintColor.setShadowLayer(10, 10, 5, Color.RED);
mDrawingView.setDrawingColor(COLORS[((Integer) v.getTag())
.intValue()]);
hideBrushPanel();
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_play, menu);
return super.onCreateOptionsMenu(menu) | true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_emboss:
mDrawingView.setFlag(3);
System.out.println("mClick Emboss");
mDrawingView.setDrawingStroke(30);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_watermark:
mDrawingView.setFlag(2);
mDrawingView.setDrawingStroke(30);
BlurMaskFilter mBlur = new BlurMaskFilter(15, BlurMaskFilter.Blur.NORMAL);
mDrawingView.mPaintColor.setMaskFilter(mBlur);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_pencil:
mDrawingView.setFlag(1);
mDrawingView.setDrawingStroke(4);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_brush:
mDrawingView.setFlag(0);
mDrawingView.setDrawingStroke(30);
if (mBrushPanel.getTranslationY() == 0) {
hideBrushPanel();
} else {
showBrushPanel();
}
break;
case R.id.action_eraser:
mDrawingView.enableEraser();
break;
case R.id.action_undo:
mDrawingView.undoOperation();
break;
case R.id.action_redo:
mDrawingView.redoOperation();
break;
case R.id.action_save: {
mDrawingView
.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mDrawingView.setDrawingCacheEnabled(true);
mDrawingView.buildDrawingCache();
Bitmap viewCache = mDrawingView.getDrawingCache();
Bitmap bitmap = viewCache.copy(viewCache.getConfig(), false);
mDrawingView.setDrawingCacheEnabled(false);
new SaveTask().execute(bitmap);
View view = findViewById(R.id.relative);
view.setDrawingCacheEnabled(true);
// Bitmap bitmap2 = view.getDrawingCache();
final Bitmap bitmap2 = bitmap.copy(Bitmap.Config.ARGB_8888,
true);
final BitmapDrawable bitmapDrawable = new BitmapDrawable(
bitmap2);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(R.layout.horizon,
(ViewGroup) findViewById(R.id.main_relative_output));
RelativeLayout rl = (RelativeLayout) layout
.findViewById(R.id.main_relative_output);
/*AlertDialog builder = new AlertDialog.Builder(
PlayActivity.this).setView(layout).show();*/
//Convert to byte array
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap2.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Intent i = new Intent(PlayActivity.this, SharingScreen.class);
i.putExtra("image",byteArray);
i.putExtra("name", name);
startActivity(i);
// rl.setBackgroundDrawable(bitmapDrawable);
}
break;
case R.id.action_cancel:
mDrawingView.clearDrawing();
// file.delete();
/*if(viewCache.isRecycled()){
viewCache.recycle();
bitmap.recycle();
}*/
break;
/*case R.id.action_share:
mDrawingView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
mDrawingView.setDrawingCacheEnabled(true);
mDrawingView.buildDrawingCache();
Bitmap viewCache = mDrawingView.getDrawingCache();
Bitmap bitmap = viewCache.copy(viewCache.getConfig(), false);
new SaveAndShare().execute(bitmap);
break;*/
default:
return super.onOptionsItemSelected(item);
}
return true;
}
}
I'm working an app which is can draw on a custom view. I want to save the drawing with a button. I tried the other solution on the other threads but nothing. please give me an example with my method below. actually, it's not my method. it's from https://github.com/msiuts/FingerPaint
Custom View
DrawView.java
public class DrawView extends View implements OnTouchListener {
private static final String TAG = "DrawView";
private final Random random = new Random();
private final int[] colors = new int[] {Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK,
Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK, Color.BLACK};
private final Paint paint = new Paint();
private Path path = new Path();
private Canvas canvas;
private Bitmap bitmap;
// deletes the screen by painting it black when the Menu Button is pressed
// this is a good method but how about save the drawing?
private OnKeyListener clearingOnKeyListener = new OnKeyListener() {
public boolean onKey(View view, int i, KeyEvent keyEvent) {
if (KeyEvent.KEYCODE_MENU == keyEvent.getKeyCode() && KeyEvent.ACTION_DOWN == keyEvent.getAction()) {
bitmap.eraseColor(Color.BLACK);
invalidate();
return true;
}
return false;
}
};
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
this.setOnTouchListener(this);
this.setOnKeyListener(clearingOnKeyListener);
paint.setColor(randomColor());
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3f);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (bitmap != null) {
if (bitmap.getHeight() == w && bitmap.getWidth() == h) {
Log.d(TAG, "rotating bitmap by 90 degree");
Matrix mtx = new Matrix();
mtx.postRotate(90, h/2, w/2);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, h, w, mtx, false);
canvas = new Canvas();
canvas.setBitmap(bitmap);
return;
} else {
bitmap.recycle();
}
}
canvas = new Canvas();
bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
canvas.setBitmap(bitmap);
}
#Override
public void onDraw(Canvas c) {
// draw to the screen
c.drawBitmap(bitmap, null, new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()), null);
}
public boolean onTouch(View view, MotionEvent event) {
// draw the new Points to our internal canvas / bitmap
if (event.getAction() == MotionEvent.ACTION_DOWN) {
paint.setColor(randomColor());
path = new Path();
path.moveTo(event.getX(), event.getY());
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
int historySize = event.getHistorySize();
for (int i=0; i < historySize; i++) {
path.lineTo(event.getHistoricalX(i), event.getHistoricalY(i));
}
path.lineTo(event.getX(), event.getY());
canvas.drawPath(path, paint);
} else {
return super.onTouchEvent(event);
}
invalidate();
return true;
}
public Bitmap getBitmap() {
return bitmap;
}
public void initBitmap(Bitmap bmap) {
bitmap = bmap;
}
/**
* Chooses a random color.
* #return the chosen color
*/
private int randomColor() {
return colors[random.nextInt(colors.length)];
}
}
Activity
Drawing Activity.java
public class DrawingActivity extends Activity {
private static final String TAG = "FingerPaint";
private DrawView drawView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw);
// restore view
drawView = (DrawView) findViewById(R.id.drawView);
Log.d(TAG, "DrawView from R is null? " + (drawView == null));
Bitmap lastDrawing = (Bitmap) getLastNonConfigurationInstance();
if (lastDrawing != null) {
Log.d(TAG, "lastDrawing is not null");
drawView.initBitmap(lastDrawing);
}
}
#Override
public Object onRetainNonConfigurationInstance() {
Bitmap bmap = null;
if (drawView != null) {
bmap = drawView.getBitmap();
Log.d(TAG, "onRetainNonConfigurationInstance returning a bitmap: " + (bmap != null));
}
return bmap;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
On the assumption you want to save the file to the devices storage, here is the solution i use...
Add permission to manifest:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Here is how I am doing it:
// Variables i needed
private String mFileName;
private Bitmap mBitmap;
// apply this listener to your button
private final View.OnClickListener ButtonListener = new View.OnCickListener(){
#Override
public void onClick(View v){
new SaveFile().execute();
}
}
private class SaveFile extends AsyncTask<Void, Void, File>{
#Override
protected File doInBackground(Void... params) {
View rootView = findViewById(R.id.drawView);
File newBackgroundBitmap = saveFileToStorage(rootView);
return newBackgroundBitmap;
}
#Override
protected void onPostExecute(File bitmapFile) {
super.onPostExecute(bitmapFile);
if(bitmapFile != null){
Toast.makeText(getBaseContext(), "Saved drawView to storage", Toast.LENGTH_SHORT).show();
}
}
}
Then here is the method doing all the work:
/**
* Saves the Bitmap File to Storage and returns the new File
* #param rootView - the View we want to capture
* #return returns the new FileName of the image.
*/
private File saveFileToStorage(View rootView){
rootView.setDrawingCacheEnabled(true);
mBitmap = rootView.getDrawingCache();
File fileDirectory = new File(Environment.getExternalStorageDirectory() + "FOLDER_NAME_YOU_WANT_TO_USE");
fileDirectory.mkdirs();
// Filename to store, Probably want to add some time stamp to make this unique
mFileName = "YOUR_FILE_NAME"+ ".png";
final File newBackgroundBitmap = new File(fileDirectory, mFileName);
try{
newBackgroundBitmap.createNewFile();
FileOutputStream outputStream = new FileOutputStream(newBackgroundBitmap);
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
Log.d(TAG, "File saved..." + " " + mFileName);
}catch(Exception e){
e.printStackTrace();
}
return newBackgroundBitmap;
}
I'm using this app to draw free lines in android
DrawerView.java
public class DrawerView extends View {
public static Paint paint;
Paint paint2 = new Paint();
public Path path = new Path();
public Path circlePath = new Path();
public static int lineCol = Color.BLUE;
public static boolean isTouchable = false;
public LayoutParams params;
public DrawerView(Context context, AttributeSet attrs){
super(context, attrs);
paint = new Paint();
paint.setAntiAlias(true);
paint.setColor(lineCol);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
}
public void onButtonPress(){
// resets the screen
path.reset();
// Calls the onDraw() method
postInvalidate();
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isTouchable){
return false;
} else {
// Gives you x and y coordinates on the Event.
float pointX = event.getX();
float pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
path.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
path.lineTo(pointX, pointY);
circlePath.reset();
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
postInvalidate();
return true;
}
}
}
DrawLines.java
public class DrawLines extends Activity {
DrawerView myView;
public Button btnReset;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.draw_line);
myView = (DrawerView)findViewById(R.id.custView);
btnReset = (Button) findViewById(R.id.button1);
btnReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// resets the screen
myView.path.reset();
// Calls the onDraw() method
myView.postInvalidate();
}
});
}
}
draw_line.xml
<Button
android:id="#+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Clear" />
<com.example.drawline.DrawerView
android:id="#+id/custView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/button1"
android:layout_margin="5dp"
custom:lineColor="#ff0099" />
It works well with me but I want to be able to select the color of line, so I added a button in draw_line.xml that when press it show a dialog that asks the user to select color. this is the code of dialog
public void openSelectColorDialog()
{
final Dialog d = new Dialog(this);
d.setTitle("Select Color");
d.setContentView(R.layout.military_list);
int image[] = { R.drawable.black, R.drawable.blue, R.drawable.yellow};
ArrayList<HashMap<String, String>> objArayList = new ArrayList<HashMap<String, String>>();
for (int i = 0; i < image.length; i++) {
HashMap<String, String> listData = new HashMap<String, String>();
listData.put("image", Integer.toString(image[i]));
objArayList.add(listData);
}
String[] from = { "image"};
int[] to = { R.id.list_image };
SimpleAdapter listAdapter = new SimpleAdapter(this, objArayList,
R.layout.military_list_item, from, to);
ListView lst1 = (ListView) d.findViewById(android.R.id.list);
lst1.setAdapter(listAdapter);
lst1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parentView, View childView, int position, long id) {
if (position == 0) {
// the code of color line
d.dismiss();
} else if (position == 1) {
// the code of blue line
d.dismiss();
} else {
// the code of yellow line
d.dismiss();
}
myView.postInvalidate();
}
});
d.show();
}
What is the code I have to add to make the color like what I selected ?
consider if I write this code
DrawerView.paint.setColor(Color.BLACK);
the whole line changes its color to the selected color and this is not what I want.
I want that the color of the new line is like what I selected and keep the old lines with its colors.
Hope anyone got my mean.
Thanks in advance.
Edit
the new code is:
ColoredPath.java
public class ColoredPath {
private Paint paint;
private Path path = new Path();
private int color;
public ColoredPath() {
paint = new Paint();
color = Color.BLACK;
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
paint.setAntiAlias(true);
paint.setColor(color);
}
public ColoredPath(int color) {
paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(4f);
paint.setAntiAlias(true);
paint.setColor(color);
}
public void setColor(int color){
this.color = color;
}
public int getColor(){
return color;
}
public void setPaint(Paint paint){
this.paint = paint;
}
public Paint getPaint() {
return paint;
}
public void setPath(Path path){
this.path = path;
}
public Path getPath() {
return path;
}
}
DrawerView.java
public class DrawerView extends View {
public Path circlePath = new Path();
public static int LINE_COLOR = 0;
public static boolean isTouchable = false;
public List<ColoredPath> paths = new ArrayList<ColoredPath>();
public ColoredPath currentPath;
public DrawerView(Context context, AttributeSet attrs){
super(context, attrs);
currentPath = new ColoredPath();
paths.add(currentPath);
}
public void newLine(int color){
System.out.println("in newLine method");
currentPath = new ColoredPath(color);
paths.add(currentPath);
//postInvalidate();
}
public void onButtonPress(){
// resets the screen
currentPath.getPath().reset();
// Calls the onDraw() method
postInvalidate();
}
#Override
protected void onDraw(Canvas canvas) {
System.out.println("size of paths: "+paths.size());
canvas.drawPath(currentPath.getPath(), currentPath.getPaint());
for(int i = 0; i < paths.size(); ++i) {
//ColoredPath coloredPath = paths.get(i);
canvas.drawPath(currentPath.getPath(), currentPath.getPaint());
}
}
public Path getLastPath() {
Path path = new Path();
for(int i = 0; i < paths.size(); ++i) {
path.addPath(paths.get(i).getPath());
}
return path;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (!isTouchable){
return false;
} else {
// Gives you x and y coordinates on the Event.
float pointX = event.getX();
float pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
currentPath.getPath().moveTo(pointX, pointY);
//getLastPath().moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
currentPath.getPath().lineTo(pointX, pointY);
//getLastPath().lineTo(pointX, pointY);
circlePath.reset();
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
postInvalidate();
return true;
}
}
}
and in MainActivity.java
if (position == 1) {
// blue
myView.newLine(Color.BLUE);
d.dismiss();
}
this works well and colors the lines but when I select any color it leads to remove the last line and I want all lines with there colors.
Because Path itself doesn't contain any information about it's color (color is managed by Canvas) I would suggest you to create new pair of (Path, Paint) for every new path with different paint and use only current pair in onTouch event. So here is some code which illustrate this idea
public class ColoredPath {
private Paint paint;
private Path path;
public ColoredPath(Paint paint, Path path) {
this.paint = paint;
this.path = path;
}
public Paint getPaint() {
return paint;
}
public Path getPath() {
return path;
}
}
private List<ColoredPath> paths = new ArrayList<ColoredPath>();
public DrawerView(Context context, AttributeSet attrs){
super(context, attrs);
//custom paint can be used here
paths.add(new ColoredPath(new Paint(), new Path()));
}
/////
#Override
protected void onDraw(Canvas canvas) {
for(ColoredPath coloredPath : paths) {
canvas.drawPath(coloredPath.getPath(), coloredPath.getPaint());
}
}
Where paths is List<ColoredPath>. And also you need field like ColoredPath currentPath.