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 the Rectangle and Larger_Rectangle classes. Now I want to do that when I touch only on the rectangle object from the rectangle class as the result I see other rectangle object from the Larger_Rectangle class.
Rectangle.class
public class Rectangle extends View {
Paint paint;
Rectangle(Context context) {
super(context);
paint = new Paint();
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.RED);
canvas.drawRect(10,30,50,70,paint);
}
}
The Larger_Rectangle class
public class Larger_Rectangle extends View {
Paint paint;
Larger_Rectangle(Context context) {
super(context);
paint = new Paint();
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLUE);
canvas.drawRect(60,100,120,150,paint);
}
}
MainActivity class
public class MainActivity extends Activity {
Rectangle rectangle;
Larger_Rectangle larger_rectangle;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
rectangle = new Rectangle(this);
setContentView(rectangle);
rectangle.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
larger_rectangle = new Larger_Rectangle(getApplicationContext());
setContentView(larger_rectangle);
return true;
}
});
}
}
I want when I touch only on the rectangle object I can see the larger_rectangle object, but in here when I touch anywhere in the touch screen I see the larger_rectangle object.
Try this code, you had views are supposed to be a class...
MainActivity.java
public class MainActivity extends Activity {
Rectangle rectangle;
Larger_Rectangle larger_rectangle;
#Override
protected void onCreate(Bundle bundle) {
super.onCreate(bundle);
rectangle = new Rectangle(this);
setContentView(rectangle);
rectangle.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
larger_rectangle = new Larger_Rectangle(getApplicationContext());
setContentView(larger_rectangle);
return true;
}
});
}
}
Rectangle.java
public class Rectangle extends View {
Paint paint;
Rectangle(Context context) {
super(context);
paint = new Paint();
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.RED);
canvas.drawRect(10,30,50,70,paint);
}
}
and finally Large_Rectangle.java...
public class Larger_Rectangle extends View {
Paint paint;
Larger_Rectangle(Context context) {
super(context);
paint = new Paint();
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.BLUE);
canvas.drawRect(60,100,120,150,paint);
}
}
I would like to add effects to my pointer. That is, while I am scrolling my finger in screen, show up effect or animation around which is showed up touched area. how to add?
I've found this:
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;
}
}
}
I have made an app that plots a point on the image where I click. Now I want to add pinch zoom in and zoom out and drag functionality. What is the best way to do it?
Thanks in advance
This is my Main Activity
public class MainActivity extends ActionBarActivity {
private RelativeLayout rl_Main;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rl_Main = (RelativeLayout) findViewById(R.id.rl_main);
rl_Main.addView(new MyView(this));
}
class MyView extends View{
Paint paint = new Paint();
Point point = new Point();
public MyView(Context context) {
super(context);
paint.setColor(Color.RED);
paint.setStrokeWidth(15);
paint.setStyle(Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
Bitmap b=BitmapFactory.decodeResource(getResources(), R.drawable.josepg);
canvas.drawBitmap(b, 0, 0, paint);
canvas.drawCircle(point.x, point.y, 1, paint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
point.x = event.getX();
point.y = event.getY();
}
invalidate();
return true;
}
}
class Point {
float x, y;
}
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;
}
}
}