I'm developing a paint activity please take a look on the code I'm working on below:
public class MyTouchEventView extends LinearLayout {
private Paint paint = new Paint();
private Path path = new Path();
private Paint circlePaint = new Paint();
private Path circlePath = new Path();
public Button btnReset;
public Button btnSave;
public LinearLayout.LayoutParams params;
public MyTouchEventView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(15f);
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
btnReset = new Button(context);
btnReset.setText("Clear Screen");
btnSave = new Button(context);
btnSave.setText("Save Image");
params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
LayoutParams.WRAP_CONTENT);
btnReset.setLayoutParams(params);
btnSave.setLayoutParams(params);
addView(btnReset);
addView(btnSave);
btnSave.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// resets the screen
path.reset();
// Calls the onDraw() method
postInvalidate();
}
});
btnReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// resets the screen
path.reset();
// Calls the onDraw() method
postInvalidate();
}
});
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint);
canvas.drawPath(circlePath, circlePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// 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();
// (circle's center x-coordinate, y-coordinate, radius of the
// circle, direction to wind the shape)
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
//circlePath.addRect(pointX - 25, pointY - 25, pointX + 25, pointY + 25, Path.Direction.CW);
/* RectF rect = new RectF(pointX - 25, pointY - 25, pointX + 25, pointY + 25);
circlePath.addRoundRect(rect, 0, 0, Path.Direction.CW);
*/
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
// Schedules a repaint.
// Force a view to draw.
postInvalidate();
return true;
}
But the problem is, I can't draw on canvas. What am I missing in here? Any help and response are truly appreciated. Thanks.
I only made few changes to your code. Check the snap shot
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/button1"
android:id="#+id/rl"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true" >
</RelativeLayout>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginLeft="14dp"
android:text="Clear" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="32dp"
android:text="Save" />
</RelativeLayout>
MainActivity
public class MainActivity extends Activity {
DrawingView dv ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dv = new DrawingView(this);
setContentView(R.layout.activity_main);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.rl);
rl.addView(dv);
Button b = (Button) findViewById(R.id.button1);
Button b1 = (Button) findViewById(R.id.button2);
b.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
dv.clear(); // on button click clear the draw
}
});
// similarly you can save the draw. i have not added.
// if you have trouble let me know
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public class DrawingView extends View {
private Paint paint = new Paint();
private Path path = new Path();
private Paint circlePaint = new Paint();
private Path circlePath = new Path();
public Button btnReset;
public Button btnSave;
public LinearLayout.LayoutParams params;
public DrawingView (Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(15f);
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
}
public void clear()
{
path.reset();
// Calls the onDraw() method
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawPath(path, paint);
canvas.drawPath(circlePath, circlePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// 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();
// (circle's center x-coordinate, y-coordinate, radius of the
// circle, direction to wind the shape)
circlePath.addCircle(pointX, pointY, 30, Path.Direction.CW);
//circlePath.addRect(pointX - 25, pointY - 25, pointX + 25, pointY + 25, Path.Direction.CW);
/* RectF rect = new RectF(pointX - 25, pointY - 25, pointX + 25, pointY + 25);
circlePath.addRoundRect(rect, 0, 0, Path.Direction.CW);
*/
break;
case MotionEvent.ACTION_UP:
circlePath.reset();
break;
default:
return false;
}
// Schedules a repaint.
// Force a view to draw.
invalidate();
return true;
}
}
}
Snap Shot
Explanation
I used a Relative layout and placed buttons accordingly.
I used another relative layout with id rl. Added custom view to the same.
I extended a view rather than Linear Layout.
I defined a method clear to clear the draw which is called onClick of clear.
I used invalidate to refresh the draw.
Edit 2:
Save:
Note: Only the draw is saved. You can save the entire screen if you want to.
Add permission in Manifest File
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Use the below to save
Button b1 = (Button) findViewById(R.id.button2);
b1.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
AlertDialog.Builder editalert = new AlertDialog.Builder(MainActivity.this);
editalert.setTitle("Please Enter the name with which you want to Save");
final EditText input = new EditText(MainActivity.this);
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) {
rl.setDrawingCacheEnabled(true);
String name= input.getText().toString();
Bitmap bitmap =rl.getDrawingCache();
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyDraw");
myDir.mkdirs();
File file = new File (myDir, name+".png");
if (file.exists ()) file.delete ();
try
{
if(!file.exists())
{
file.createNewFile();
}
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 10, ostream);
// System.out.println("saving......................................................"+path);
ostream.close();
rl.invalidate();
}
catch (Exception e)
{
e.printStackTrace();
}finally
{
rl.setDrawingCacheEnabled(false);
}
}
});
editalert.show();
}
});
Related
I am making an android colouring app which uses the draw feature. I have it so that there are multiple colours that the user can choose from and they can select a colour and draw however when they select a new colour it changes all previously drawn lines as well not just the new lines being drawn. Any help on how I can rectify this and have multiple colours used on the drawing is greatly appreciated. Some of my code is below: The first is the colouring class
public class Colouring extends View {
// setup initial color
private int paintColor = Color.BLACK;
private Paint drawPaint;
private Path drawPath;
// stores the path
//private Path path = new Path();
public Colouring(Context context, AttributeSet attrs) {
super(context, attrs);
setFocusable(true);
setFocusableInTouchMode(true);
setupcolour();
}
private void setupcolour() {
// Setup paint with color and stroke styles
drawPath = new Path();
drawPaint = new Paint();
drawPaint.setColor(paintColor);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(15);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(drawPath, drawPaint);
}
public void setColor(String newColor) {
invalidate();
paintColor = Color.parseColor(newColor);
drawPaint.setColor(paintColor);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
// Checks for the event that occurs
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
drawPath.moveTo(pointX, pointY);
return true;
case MotionEvent.ACTION_MOVE:
drawPath.lineTo(pointX, pointY);
break;
default:
return false;
}
// Force a view to draw again
invalidate();
return true;
}
}
and the second is the main activity where the drawing happens.
public class ColourImage extends Activity {
private Colouring drawView;
private ImageButton currcolour, save;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_colour_image);
drawView = (Colouring)findViewById(R.id.colouringBook);
LinearLayout paintLayout = (LinearLayout) findViewById(R.id.colours);
currcolour = (ImageButton) paintLayout.getChildAt(0);
currcolour.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
save = (ImageButton)findViewById(R.id.save);
}
public void saveclicked(View view){
drawView.setDrawingCacheEnabled(true);
String saveImage = MediaStore.Images.Media.insertImage(
getContentResolver(), drawView.getDrawingCache(),
UUID.randomUUID().toString()+".png", "colouredImage");
if(saveImage!=null){
Toast savedToast = Toast.makeText(getApplicationContext(),
"Your colouring has been saved to your phone", Toast.LENGTH_SHORT);
savedToast.show();
}
else{
Toast unsavedToast = Toast.makeText(getApplicationContext(),
"Your colouring was not saved", Toast.LENGTH_SHORT);
unsavedToast.show();
}
drawView.destroyDrawingCache();
}
public void paintClicked(View view){
if(view!=currcolour){
ImageButton colourImage = (ImageButton)view;
String color = view.getTag().toString();
drawView.setColor(color);
colourImage.setImageDrawable(getResources().getDrawable(R.drawable.paint_pressed));
currcolour.setImageDrawable(getResources().getDrawable(R.drawable.paint));
currcolour=(ImageButton)view;
}
}
}
Thanks again :)
I am trying to make drawing brush application here I am able to draw by touching finger..but what i want is user can select different colors and draw it..can any one help me with this?
public class MyTouchEventView extends View {
private Paint paint = new Paint();
private Path path = new Path();
private Paint circlePaint = new Paint();
private Path circlePath = new Path();
public Button btnReset;
public LayoutParams params;
private Spinner sp;
public MyTouchEventView(Context context) {
super(context);
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(15f);
circlePaint.setAntiAlias(true);
circlePaint.setColor(Color.BLUE);
circlePaint.setStyle(Paint.Style.STROKE);
circlePaint.setStrokeJoin(Paint.Join.MITER);
circlePaint.setStrokeWidth(4f);
sp=new Spinner(context);
btnReset = new Button(context);
btnReset.setText("Clear Screen");
params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
btnReset.setLayoutParams(params);
btnReset.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
// resets the screen
path.reset();
// Calls the onDraw() method
postInvalidate();
}
});
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawPath(path, paint);
canvas.drawPath(circlePath, circlePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float pointX = event.getX();
float pointY = event.getY();
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;
}
// Schedules a repaint.
// Force a view to draw.
postInvalidate();
return true;
}
}
DrawingBrush.java
public class DrawingBrush extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyTouchEventView tv = new MyTouchEventView(this);
setContentView(tv);
addContentView(tv.btnReset, tv.params);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
finish();
}
}
There are ready made solutions available hope it helps you.
Example1
Example2
Example3
Example4
I try to draw on ImageView from a file resource. Here is my code:
private Bitmap myBitmap;
private Bitmap mutableBitmap;
private Canvas canvas;
private Paint paint;
private ImageView img;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.layout_imagefullscreen);
paint = new Paint();
paint.setStrokeWidth(11);
paint.setColor(Color.YELLOW);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
View decorView = getWindow().getDecorView();
int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
decorView.setSystemUiVisibility(uiOptions);
...
if (imageFileFullPathName != null) {
try {
File imgFile = new File (imageFileFullPathName);
if (imgFile.exists ()) {
myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
mutableBitmap = myBitmap.copy(Bitmap.Config.ARGB_8888, true);
canvas = new Canvas(mutableBitmap);
img.setImageBitmap(mutableBitmap);
Matrix m = img.getImageMatrix();
canvas.setMatrix(m);
}
} catch (Exception e) {
e.printStackTrace ();
}
}
img.setOnTouchListener (new OnTouchListener() {
float startX, startY;
float stopX, stopY;
#Override
public boolean onTouch (View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
startX = event.getX();
startY = event.getY();
Log.i("---> DOWN X", String.valueOf(startX));
Log.i("---> DOWN Y", String.valueOf(startY));
break;
case MotionEvent.ACTION_MOVE:
stopX = event.getRawX();
stopY = event.getRawY();
Log.i("---> MOVE X", String.valueOf(stopX));
Log.i("---> MOVE Y", String.valueOf(stopY));
canvas.drawLine(startX, startY, stopX, stopY, paint);
img.invalidate();
startX = event.getRawX();
startY = event.getRawY();
img.setImageBitmap(mutableBitmap);
break;
case MotionEvent.ACTION_UP:
stopX = event.getRawX();
stopY = event.getRawY();
Log.i("---> UP X", String.valueOf(stopX));
Log.i("---> UP Y", String.valueOf(stopY));
canvas.drawLine(startX, startY, stopX, stopY, paint);
img.invalidate();
break;
default:
break;
}
v.performClick();
return true;
}
});
}
}'
But when I move my finger on the ImageView, the line does not follow my finger, it limits only on the top left of the screen instead. I also try to change getRawX() to getX(), but this issue persists. I believe the problem is something about coordinates transformation, but could not figure how to solve it. Please help, thanks!
Layout xml file:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="#color/Black">
<ImageView
android:id="#+id/imagefullscreenview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:src="#drawable/ic_launcher"/>
</LinearLayout>
From your code, it looks like you are trying to drawing following the touched finger. So here is how you draw...
public class MainActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, OnTouchListener {
SurfaceView sv;
SurfaceHolder sh;
RenderingThread thread;
Canvas canvas = null;
int Width = 0, Height = 0;
Button btnClear;
Path path = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
try{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_main);
sv = (SurfaceView)findViewById(R.id.sv);
sv.setOnTouchListener(this);
btnClear = (Button)findViewById(R.id.btnClear);
path = new Path();
sh = sv.getHolder();
if(sh != null)
{
sh.addCallback(this);
}
else
{
Toast.makeText(getApplicationContext(), "Failed to initialize", Toast.LENGTH_SHORT).show();
finish();
}
}catch(Throwable ex)
{
ex.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed to start", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
try{
Width = width;
Height = height;
thread = new RenderingThread(holder, width, height);
canvas = new Canvas(thread.drawingBitmap);
thread.start();
}catch(Throwable ex) {
ex.printStackTrace();
Toast.makeText(getApplicationContext(), "Failed to initialize", Toast.LENGTH_SHORT).show();
finish();
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
sv.setWillNotDraw(false);
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.RequestStop();
}
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction())
{
case MotionEvent.ACTION_DOWN:
path.moveTo(event.getRawX(), event.getRawY());
break;
case MotionEvent.ACTION_MOVE:
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAntiAlias(true);
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeWidth(5);
CornerPathEffect pathEffect = new CornerPathEffect(45);
paint.setPathEffect(pathEffect);
path.lineTo(event.getRawX(), event.getRawY());
canvas.drawPath(path, paint);
//
Log.i("minor",""+event.getTouchMinor());
Log.i("major",""+event.getTouchMajor());
break;
case MotionEvent.ACTION_UP:
path.reset();
break;
}
return true;
}
#Override
public void onClick(View v) {
switch(v.getId())
{
case R.id.btnClear:
canvas.drawColor(Color.WHITE);
break;
}
}
}
Here btnClear is a button in XML from which you can clear the canvas.
Here is the XML
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<SurfaceView
android:id="#+id/sv"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/btnClear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clear"
android:textSize="18sp"
android:textColor="#ffffff"
android:background="#555555"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:onClick="onClick" />
</RelativeLayout>
And here is the rendering thread...
public class RenderingThread extends Thread {
private boolean keepRunning = true;
private SurfaceHolder holder = null;
public Bitmap drawingBitmap = null;
private int width = 0, height = 0;
public RenderingThread(SurfaceHolder holder, int width, int height)
{
this.holder = holder;
this.width = width;
this.height = height;
drawingBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
}
public void RequestStop()
{
keepRunning = false;
interrupt();
}
#Override
public void run() {
while(keepRunning)
{
try{
Thread.sleep(30);
//
if(holder != null && drawingBitmap != null)
{
Canvas canvas = holder.lockCanvas();
if(canvas != null)
{
canvas.drawColor(Color.WHITE);
Rect src = new Rect(0, 0, drawingBitmap.getWidth(), drawingBitmap.getHeight());
Rect dst = new Rect(0, 0, width, height);
canvas.drawBitmap(drawingBitmap, src, dst, new Paint());
//
holder.unlockCanvasAndPost(canvas);
}
}
}catch(Throwable ex) {
ex.printStackTrace();
}
}
}
}
Good Luck. :)
Hi using myview in one class.am drawing some lines,after that if am clicking button then am going to some other class,then again i am coming back to previous class,but here i drawn lines is not there,but in my case i need to show that drawn lines when i come back to previous activity...can you any one suggest me..thnkyou
MainActivity
public class MainActivity extends Activity {
MyView myview;
RelativeLayout rl;
Button b1;
public boolean action = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b1=(Button)findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent i=new Intent(MainActivity.this,Activity2.class);
startActivity(i);
}
});
rl = (RelativeLayout) findViewById(R.id.layout);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
// mPaint.setColor(0xFFFF0000);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(6);
myview = new MyView(this);
myview.setId(004);
RelativeLayout.LayoutParams lp6 = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
myview.setLayoutParams(lp6);
// myview.setBackgroundResource(R.drawable.booklet);
lp6.setMargins(10, 100, 10, 10);
// lp6.setMargins(25, 50, 8,70);
rl.addView(myview, lp6);
}
private Paint mPaint;
private Bitmap mBitmap;
public void colorChanged(int color) {
mPaint.setColor(color);
}
public class MyView extends View {
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
// clearAllResources();
}
#Override
protected void onDraw(Canvas canvas) {
if (action) {
invalidate();
}
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
private float mX, mY;
private final float TOUCH_TOLERANCE = 2;
private void touch_start(float x, float y) {
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
// commit the path to our offscreen
mCanvas.drawPath(mPath, mPaint);
// kill this so we don't double draw
mPath.reset();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}
}
Activity2
public class Activity2 extends Activity {
Button b1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.acticity2);
b1=(Button)findViewById(R.id.button1);
b1.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent i=new Intent(Activity2.this,MainActivity.class);
startActivityForResult(i, 0);
}
});
}
}
Create a line class that has following properties
float startX, float startY, float stopX, float stopY, Paint paint
Then create List to contain your line instances. Each time you create a line, create a new line instance, set its data and add it to the list. In onDraw, iterate through the list and draw each line with the data you stored.
Problem with your code is that you a launching a new instance of activity whenever button is clicked.
Instead of startActivity() , try calling finish() from Activity2.
OR you can use setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
to bring previous instance of MainActivity to front.
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
//finish(); OR
intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
}
Actually i am doing image editing in android and using canvas ... but i don't know ....
how to work with canvas and UI together..??
how use buttons and other widgets with canvas...??
how to make polygon editable .. so that if i touch any point then it hould highlight and i can resize the polygon.
There is my code:
public class Crop_Image_Activity1 extends Activity implements OnClickListener
{
static int count=0,i=0,j=0;
ImageView img1;
Button bt1,bt2;
Path path=new Path();
Paint mPaint;
float x_current,y_current;
float x0,y0;
float x1,y1;
float pointx[]=new float[20];
float pointy[]=new float[20];
String num;
MyView view1;
ViewGroup.LayoutParams params;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_crop__image__activity1);
img1=(ImageView)findViewById(R.id.imageView1);
bt1=(Button)findViewById(R.id.button1);
bt2=(Button)findViewById(R.id.button2);
//img1.setImageResource(R.drawable.pic1);
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setColor(0xFFFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(1);
view1=new MyView(this);
params =new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
addContentView(view1, params);
// bt1.setOnClickListener(this);
// bt2.setOnClickListener(this);
}
public class MyView extends View implements android.view.GestureDetector.OnGestureListener{
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;
private GestureDetector gestureScanner;
public MyView(Context c)
{
super(c);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
gestureScanner=new GestureDetector(this);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
}
#SuppressLint("DrawAllocation")
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
canvas.drawPath(mPath, mPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
return gestureScanner.onTouchEvent(event);
}
public boolean onDown(MotionEvent arg0)
{
x1=arg0.getX();
y1=arg0.getY();
if(count==-1)
{
mPath.reset();
mPath.moveTo(pointx[j],pointy[j]);
}
else if(count==0)//// storing initial points
{
mPath.moveTo(x1, y1);
mCanvas.drawCircle(x1,y1,10, mPaint);
x0=x1;
y0=y1;
pointx[i]=x1; /// storing all points in array
pointy[i]=y1;
}
else if(count>0)
{
mPath.moveTo(x_current,y_current);
mCanvas.drawCircle(x_current,y_current,10, mPaint);
}
count++;
invalidate();
return true;
}
#Override
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,float arg3)
{
x_current=arg1.getX();
y_current=arg1.getY();
i++;
pointx[i]=x_current;
pointy[i]=y_current;
mPath.lineTo(x_current,y_current);
mCanvas.drawPath(mPath, mPaint);
invalidate();
return true;
}
public boolean onSingleTapUp(MotionEvent e)
{
mPath.moveTo(x_current,y_current);
mPath.lineTo(x0,y0);
mCanvas.drawPath(mPath, mPaint);
invalidate();
return true;
}
public boolean onDoubleTapUp(MotionEvent e)
{
return false;
}
public void onLongPress(MotionEvent e)
{
for(j=0;j<=i;j++)
{
if((e.getX()>pointx[j]-20 && e.getX()<pointx[j]+20) && (e.getY()>pointy[j]-20 && e.getY()<pointy[j]+20))
{
mPaint.setColor(Color.BLUE);
mCanvas.drawCircle(pointx[j],pointy[j],20, mPaint);
count=-1;
invalidate();
mPaint.setColor(0xFFFF0000);
break;
}
}
}
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,float distanceX, float distanceY)
{
return false;
}
#Override
public void onShowPress(MotionEvent e)
{
}
}
public void onClick(View view)
{
switch(view.getId())
{
case R.id.button1:
break;
case R.id.button2:
// Intent intent1=new Intent();
// startActivity(intent1);
break;
}
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_crop__image__activity1, menu);
return true;
}
}
If you want both your custom view and components from xml layout to appear on the screen, create a RelativeLayout and set it as activity's view. Then add your cutom view to that layout and inflate the view from your .xml file using relative layout as a parent.
Like this:
RelativeLayout relativeLayout = new RelativeLayout(this);
setContentView(relativeLayout);
layout.addView(myView);
LayoutInflater inflater = LayoutInflater.from(this);
inflater.inflate(R.layout.activity_crop__image__activity1, relativeLayout);
About the last question try sth like this in your onTouch method
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN:
tx = event.getX(); // get coordinates when you touch the screen
ty = event.getY();
break;
case MotionEvent.ACTION_MOVE:
newX = event.getX(); // get coordinates when you move the finger
newY = event.getY();
for(int i = 0; i < pointx.length; i++){ // iterate over points array
if(((tx - pointx[i])*(tx - pointx[i]) + (ty - pointy[i])*(ty - pointy[i])) < 20){
// if you touched within 20 pixels of the polygon's vertex
// ...
// create Path anew replacing that vertex with coordinates newX and newY
}
}
break;
}
return true;
}