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;
}
Related
I use Canvas to draw bitmap by touch screen but they don't show bitmap on apps.
public class MainActivity extends Activity {
public LinearLayout screenlayout;
public void draw (int x, int y){
Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.dam);
Canvas canvas=new Canvas(b);
canvas.drawBitmap(b, x, y, null);
}
public void onCreate(Bundle saveInstanceState){
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_main);
final LinearLayout screenlayout= (LinearLayout)findViewById(R.id.screenlayout);
screenlayout.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) event.getRawX();
int y = (int) event.getRawY();
draw(x,y);
break;
case MotionEvent.ACTION_MOVE:
break;
default:
break;
}
return true;
}
});
}
}
As Ganpat Kaliya answer, I provide another code to solve this problem. Thanks to Ganpat Kaliya.
public class MainActivity extends Activity {
public static float vtx;
public static float vty;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Test view = new Test(this);
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT);
addContentView(view, params);
view.setOnTouchListener(new OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
float a = event.getX();
float b = event.getY();
vtx=a;
vty=b;
v.invalidate();
return true;
}
});
}
}
And:
public class Test extends View {
public Test(Context context) {
super(context);
}
public void draw(Canvas canvas) {
float x=MainActivity.vtx;
float y=MainActivity.vty;
Paint paint = new Paint();
paint.setColor(Color.GREEN);
paint.setStrokeWidth(6);
canvas.drawLine(10,10,50,50,paint);
paint.setColor(Color.RED);
canvas.drawLine(50, 50, 90, 10, paint);
canvas.drawCircle(50, 50, 3, paint);
canvas.drawCircle(x,y,10,paint);
Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.dam);
canvas.drawBitmap(b, x, y, null);
}
}
I'm trying to make an Activity in which the canvas color changes when you tap the canvas.
With the code I now have, I get this error:
Attempt to invoke virtual method 'void android.graphics.Canvas.drawRect(float, float, float, float, android.graphics.Paint)' on a null object reference
This is a part of my Activity code.
public class ColorActivity extends Activity {
private float x = 0;
private float y = 0;
public Canvas canvas;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color);
setContentView(new MyView(this));
}
public class MyView extends View {
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
Paint paintCanvas = new Paint();
paintCanvas.setStyle(Paint.Style.FILL);
paintCanvas.setColor(Color.WHITE);
paintCanvas.setColor(Color.parseColor("#F44336"));
canvas.drawRect(0, 0, x, y, paintCanvas);
}
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
Paint repaintCanvas = new Paint();
repaintCanvas.setStyle(Paint.Style.FILL);
repaintCanvas.setColor(Color.WHITE);
repaintCanvas.setColor(Color.parseColor("#2196F3"));
canvas.drawRect(0, 0, 100, 100, repaintCanvas);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
Log.d("LOG","Move");
invalidate();
break;
case MotionEvent.ACTION_UP:
Log.d("LOG", "Up");
invalidate();
break;
}
return super.onTouchEvent(event);
}
}
What am I doing wrong?
I think I know what is your problem. Invalidate calls again to the onDraw() method and it overwrites whatever you paint in the onTouchEvent method.
Try the following code:
public class ColorActivity extends Activity {
private float x = 0;
private float y = 0;
public Canvas canvas;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_color);
setContentView(new MyView(this));
}
public class MyView extends View {
Paint paintCanvas;
public MyView(Context context) {
super(context);
paintCanvas = new Paint();
paintCanvas.setStyle(Paint.Style.FILL);
paintCanvas.setColor(Color.WHITE);
paintCanvas.setColor(Color.parseColor("#F44336"));
// TODO Auto-generated constructor stub
setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int x = getWidth();
int y = getHeight();
canvas.drawRect(0, 0, x, y, paintCanvas);
}
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
paintCanvas.setStyle(Paint.Style.FILL);
paintCanvas.setColor(Color.WHITE);
paintCanvas.setColor(Color.parseColor("#2196F3"));
invalidate();
break;
case MotionEvent.ACTION_MOVE:
Log.d("LOG","Move");
invalidate();
break;
case MotionEvent.ACTION_UP:
Log.d("LOG", "Up");
invalidate();
break;
}
return super.onTouchEvent(event);
}
}
Your Canvas is null. You will only get it inside onDraw(Canvas canvas) which is responsible for drawing on your Canvas. In your onTouchEvent, set some instance variables (such as color, positions etc.) and call invalidate(), then onDraw will be triggered and you can draw your Canvas with desired needs which you will get from the instance values you set in onTouchEvent.
This is my ImageView in androidmanifest file.
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="+id/imageview1"></ImageView>
I drawn a circle on imageview on touch but the circle is drawn at left corner top.
This is my code:
ImageView myimage=(ImageView)findViewById(R.id.imageview1);
myimage.setImageResource(R.drawable.penguins);
BitmapDrawable bmpdraw=(BitmapDrawable)myimage.getDrawable();
Bitmap bmp=bmpdraw.getCopy().config();
Canvas m_canvas=new Canvas(bmp);
public void onTouch(View v,MotionEvent event){
int x=event.getX();
int y=event.getY();
canvas.drawCircle(x,y,10,paint);
myimage.setBitmap(bmp);
}
I came to know that canvas position is different when compared with imageview.
Try to following code .
my_canvas.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/rl_main"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</RelativeLayout>
MyCanvas.java
public class MyCanvas extends Activity {
private RelativeLayout rl_Main;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms_read);
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.images);
canvas.drawBitmap(b, 0, 0, paint);
canvas.drawCircle(point.x, point.y, 100, 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 app which paints a circle with a Touch event on the screen. The next code works fine:
Class Punto extends view{
Paint paint;
Point point = new Point();
Public Punto(Context contex){
super(context);
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
paint.setColor(Color.BLUE);
canvas.drawCircle(point.x,point.y,10,paint);
}
#Override
public boolean onTouchEvent (MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN :
point.x = event.getX();
point.y = event.getY();
break;
}
return true;
}
class Point{
float x,y;
}
Activity:
public class Pintar extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Punto punto = new Punto(this);
setContentView(punto);
}
However I need that the circle be painted on a picture (in my case is a market's plane) but I don't know how I can do this.
Simply extend an ImageView:
class Punto extends ImageView {
I'm sorry, I assumed that the code you posted compiled...
Try this:
public class TouchImage extends ImageView {
Paint paint = new Paint();
Point point = new Point();
public TouchImage(Context context, AttributeSet attrs) {
super(context, attrs);
paint.setColor(Color.BLUE);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(point.x, point.y, 10, 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;
}
}
With a layout like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Use your reverse package name, for instance "example.com" is -->
<com.example.TouchImage
android:id="#+id/touchImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/map" />
</LinearLayout>
And an Activity that intercepts the coordinates when the TouchImage is touched:
public class Example extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TouchImage touchImage = (TouchImage) findViewById(R.id.touchImage);
touchImage.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
// Call the existing onTouchEvent() in TouchImage,
// if it draws a circle fetch the coordinates
if(v.onTouchEvent(event)) {
// Do something with event.getX(), event.getY()
}
return true;
}
});
}
}
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;
}
}
}