Canvas Drawing is not resetting on button click - android

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

Related

get Bitmap from drawer view using finger

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

the stroke width of the complete drawing changes

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.

Change the color of line draw line android

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.

How to draw a path on an Android canvas with animation?

I'm making an Android app and I've got a tricky thing to do.
I need to draw a path on a canvas but the drawing should be animated (ie. drawing point after point with a slight delay).
Is it possible to make something like this using Android SDK?
If not, how could I produce this effect?
Try this code, I used it to draw a heartbeat using Path & Canvas:
public class TestActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new HeartbeatView(this));
}
public static class HeartbeatView extends View {
private static Paint paint;
private int screenW, screenH;
private float X, Y;
private Path path;
private float initialScreenW;
private float initialX, plusX;
private float TX;
private boolean translate;
private int flash;
private Context context;
public HeartbeatView(Context context) {
super(context);
this.context=context;
paint = new Paint();
paint.setColor(Color.argb(0xff, 0x99, 0x00, 0x00));
paint.setStrokeWidth(10);
paint.setAntiAlias(true);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStyle(Paint.Style.STROKE);
paint.setShadowLayer(7, 0, 0, Color.RED);
path= new Path();
TX=0;
translate=false;
flash=0;
}
#Override
public void onSizeChanged (int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
screenW = w;
screenH = h;
X = 0;
Y = (screenH/2)+(screenH/4)+(screenH/10);
initialScreenW=screenW;
initialX=((screenW/2)+(screenW/4));
plusX=(screenW/24);
path.moveTo(X, Y);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
//canvas.save();
flash+=1;
if(flash<10 || (flash>20 && flash<30))
{
paint.setStrokeWidth(16);
paint.setColor(Color.RED);
paint.setShadowLayer(12, 0, 0, Color.RED);
}
else
{
paint.setStrokeWidth(10);
paint.setColor(Color.argb(0xff, 0x99, 0x00, 0x00));
paint.setShadowLayer(7, 0, 0, Color.RED);
}
if(flash==100)
{
flash=0;
}
path.lineTo(X,Y);
canvas.translate(-TX, 0);
if(translate==true)
{
TX+=4;
}
if(X<initialX)
{
X+=8;
}
else
{
if(X<initialX+plusX)
{
X+=2;
Y-=8;
}
else
{
if(X<initialX+(plusX*2))
{
X+=2;
Y+=14;
}
else
{
if(X<initialX+(plusX*3))
{
X+=2;
Y-=12;
}
else
{
if(X<initialX+(plusX*4))
{
X+=2;
Y+=6;
}
else
{
if(X<initialScreenW)
{
X+=8;
}
else
{
translate=true;
initialX=initialX+initialScreenW;
}
}
}
}
}
}
canvas.drawPath(path, paint);
//canvas.restore();
invalidate();
}
}
}
It uses drawing a Path point by point with couple of effects using counters. You can take what you need and transfer it to SurfaceView which is more efficient.
I hope this is what you are looking for. It draws the path on user touch, you could simply tweek it to achieve what you desire.
public class MyCanvas extends Activity implements OnTouchListener{
DrawPanel dp;
private ArrayList<Path> pointsToDraw = new ArrayList<Path>();
private Paint mPaint;
Path path;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
dp = new DrawPanel(this);
dp.setOnTouchListener(this);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mPaint = new Paint();
mPaint.setDither(true);
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(30);
FrameLayout fl = new FrameLayout(this);
fl.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
fl.addView(dp);
setContentView(fl);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
dp.pause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
dp.resume();
}
public class DrawPanel extends SurfaceView implements Runnable{
Thread t = null;
SurfaceHolder holder;
boolean isItOk = false ;
public DrawPanel(Context context) {
super(context);
// TODO Auto-generated constructor stub
holder = getHolder();
}
#Override
public void run() {
// TODO Auto-generated method stub
while( isItOk == true){
if(!holder.getSurface().isValid()){
continue;
}
Canvas c = holder.lockCanvas();
c.drawARGB(255, 0, 0, 0);
onDraw(c);
holder.unlockCanvasAndPost(c);
}
}
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
synchronized(pointsToDraw)
{
for (Path path : pointsToDraw) {
canvas.drawPath(path, mPaint);
}
}
}
public void pause(){
isItOk = false;
while(true){
try{
t.join();
}catch(InterruptedException e){
e.printStackTrace();
}
break;
}
t = null;
}
public void resume(){
isItOk = true;
t = new Thread(this);
t.start();
}
}
#Override
public boolean onTouch(View v, MotionEvent me) {
// TODO Auto-generated method stub
synchronized(pointsToDraw)
{
if(me.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(me.getX(), me.getY());
//path.lineTo(me.getX(), me.getY());
pointsToDraw.add(path);
}else if(me.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(me.getX(), me.getY());
}else if(me.getAction() == MotionEvent.ACTION_UP){
//path.lineTo(me.getX(), me.getY());
}
}
return true;
}
}
I have made it with ObjectAnimator.
We have any Path and our CustomView (in wich we'll draw our path)
private CustomView view;
private Path path;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = findViewById(R.id.custom_view);
path = new Path();
path.moveTo(0f, 0f);
path.lineTo(getResources().getDimension(R.dimen.point_250), 0f);
path.lineTo(getResources().getDimension(R.dimen.point_250), getResources().getDimension(R.dimen.point_150));
findViewById(R.id.btnStart).setOnClickListener(v -> {
test();
});
}
private void test() {
ValueAnimator pathAnimator = ObjectAnimator.ofFloat(view, "xCoord", "yCoord", path);
pathAnimator.setDuration(5000);
pathAnimator.start();
}
And just pass our "xCoord" and "yCoord" to CustomView
public class CustomView extends View {
private Paint paint;
private float xCoord;
private float yCoord;
private Path path = new Path();
public void setXCoord(float xCoord) {
this.xCoord = xCoord;
}
public void setYCoord(float yCoord) {
this.yCoord = yCoord;
path.lineTo(xCoord, yCoord);
invalidate();
}
public CustomView(Context context) {
super(context);
init();
}
public CustomView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
void init() {
paint = new Paint();
paint.setAntiAlias(true);
paint.setDither(true);
paint.setColor(Color.BLACK);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(20);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint);
}
}
This might help... It draws adjacent circles instead of a path to simulate an animatable path.
public class PathAnimatable {
private final float CIRCLE_SIZE = 2.5f;
public float SPPED_SCALE = 1f;
private float steps = 0;
private float pathLength;
private PathMeasure pathMeasure;
private float totalStepsNeeded;
private float[] point = new float[]{0f, 0f};
private float stride;
public PathAnimatable() {
this(null);
}
public PathAnimatable(Path path) {
super(path);
init();
}
private void init() {
pathMeasure = new PathMeasure(path, false);
pathLength = pathMeasure.getLength();
stride = CIRCLE_SIZE * 0.5f;
totalStepsNeeded = pathLength / stride;
steps = 0;
}
#Override
public void setPath(Path path) {
super.setPath(path);
init();
}
// Called this from your locked canvas loop function
public void drawShape(Canvas canvas, Paint paint) {
if (steps <= pathLength) {
for (float i = 0; i < steps ; i += stride) {
pathMeasure.getPosTan(i, point, null);
canvas.drawCircle(point[0], point[1], CIRCLE_SIZE, paint);
}
steps += stride * SPPED_SCALE;
} else {
steps = 0;
}
}
}

Draw Circle on touch

I am trying to draw a circle where user touches screen .
public class MainActivity extends Activity implements OnTouchListener {
LinearLayout layout;
float x=0;
float y=0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_main);
layout=(LinearLayout)findViewById(R.id.layout);
layout.addView(new CustomView(MainActivity.this));
}
public class CustomView extends View {
Bitmap mBitmap;
Paint paint;
public CustomView(Context context) {
super(context);
mBitmap = Bitmap.createBitmap(400, 800, Bitmap.Config.ARGB_8888);
paint=new Paint();
paint.setColor(Color.RED);
paint.setStyle(Style.FILL);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.setBitmap(mBitmap);
canvas.drawCircle(x, y, 50, paint);
Toast.makeText(MainActivity.this, "DDD", 1).show();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
layout.invalidate();
}
return false;
}}
I would do it this way:
public class TestActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new DrawingView(this));
}
class DrawingView extends SurfaceView {
private final SurfaceHolder surfaceHolder;
private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
public DrawingView(Context context) {
super(context);
surfaceHolder = getHolder();
paint.setColor(Color.RED);
paint.setStyle(Style.FILL);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN) {
if (surfaceHolder.getSurface().isValid()) {
Canvas canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.BLACK);
canvas.drawCircle(event.getX(), event.getY(), 50, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
return false;
}
}
}
The is your version with fixes to make it work:
public class MainActivity extends Activity {
LinearLayout layout;
float x = 0;
float y = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
layout=(LinearLayout)findViewById(R.id.layout);
layout.addView(new CustomView(MainActivity.this));
}
public class CustomView extends View {
Bitmap mBitmap;
Paint paint;
public CustomView(Context context) {
super(context);
mBitmap = Bitmap.createBitmap(400, 800, Bitmap.Config.ARGB_8888);
paint = new Paint();
paint.setColor(Color.RED);
paint.setStyle(Style.FILL);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, 50, paint);
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
x = event.getX();
y = event.getY();
invalidate();
}
return false;
}
}
}

Categories

Resources