I'm quite new to android, but basically I want to set up a program so that when the user clicks on an imageview, a dot is drawn where they click. I have tried many times but just don't seem to be able to get it to work, and help would be much appreciated.So far I have
package com.smallbore.smallbore;
import android.app.Activity;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
public class targetenter extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.targetenter);
ImageView v = (ImageView) findViewById(R.id.imageView1);
v.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
TextView t1 = (TextView) findViewById(R.id.textView2);
TextView t2 = (TextView) findViewById(R.id.textView3);
t1.setText("X: "+arg1.getX());
t2.setText("Y: "+arg1.getY());
int x = (int)arg1.getX();
int y = (int)arg1.getY();
int width = 50;
int height = 50;
ShapeDrawable mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
ImageView v = (ImageView) findViewById(R.id.imageView1)
v.setImageDrawable(mDrawable);
return false;
}
});
};
}
To draw the dots, you'll probably have to use a custom View and override onTouchEvent and onDraw. onTouchEvent will give you the x,y coordinates of the touch event and in onDraw you can draw a circle at this point to the canvas that the framework provides to this method. If you want to clear previous dots, you only need to keep track of the last x,y coordinates. Otherwise, you'll need to keep a running list (ArrayList or something like that).
In your shoes, I'd probably subclass ImageView so that I get the image drawing stuff for free. Call super.onDraw(canvas) inside the overridden onDraw method, and then draw your dots (canvas.drawCircle).
The Android SDK contains a pretty good example : http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/DrawPoints.html
You just need to make SampleView handling click event, and get it displaying the image in SampleView.onDraw method.
Related
I'm still learning Android, and I decided to download an example paint application to fiddle with that and learn a bit about how Android handles graphics/drawables/painting. The code I have shows a green and red 'V' in the upper left corner, and a red dot that follows where you touch.
However, I found that the screen is being redrawn each time, so I can't use it as a painting tool. It's almost as if I'm dumping a bucket of white paint over the surface and then redrawing the circle. How can I make it so that the red dot that follows your finger leaves a trail? Here's the code.
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
public class MainActivity extends Activity implements OnTouchListener {
private float x;
private float y;
private int moveX;
Paint paint = new Paint();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyCustomPanel view = new MyCustomPanel(this);
ViewGroup.LayoutParams params =
new ViewGroup.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
addContentView(view, params);
view.setOnTouchListener(this);
}
private class MyCustomPanel extends View {
public MyCustomPanel(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
paint.setColor(Color.GREEN);
paint.setStrokeWidth(6);
canvas.drawLine(moveX,10,50,50,paint);
paint.setColor(Color.RED);
canvas.drawLine(50, 50, 90, 10, paint);
canvas.drawCircle(50, 50, 3, paint);
moveX++;
canvas.drawCircle(x,y,3,paint);
}
}
public boolean onTouch(View v, MotionEvent event) {
x = event.getX();
y = event.getY();
v.invalidate();
return true;
}
}
For example, save the circles in an ArrayList. Make an ArrayList and save every xy coordinates from touch as a point.The following code is just from scratch, could not test it at the moment, so if anything is not working let me know and I will give a an example when I am at home.
private ArrayList<Point> pointList = new ArrayList<Point>
Then in On Touch:
Point xyPoint = new Point();
xyPoint.x = event.getX();
xyPoint.y = event.getY();
pointList.add(xyPoint);
invalidate();
and in onDraw, do a for-loop to get all points and draw each one:
for(int i=0;i<pointList.size();i++){
Point p = pointList.get(i);
canvas.drawCircle(p.x, p.y, 2, paint);
}
This draws circles with 2px diameter where Your finger touches. But this is just an simple example, there is a lot of more You can do and that look better. You should learn about draw on path and how to draw rects and ovales etc. Here is a good example of how to draw on path:
http://android-er.blogspot.de/2011/08/drawpath-on-canvas.html
I'm trying to draw different random values from an array, but linking them with lines, so it looks likes the values of a continue function. I have done it quite good with this app:
package android.nacho.Graphic2D;
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import java.util.Random;//included random
public class Graphic2D extends Activity{
DrawView drawView;
//private Button btnAsyncTask;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
int randomInt;
//note a single Random object is reused here
Random randomGenerator = new Random();
int Maxsize=800;
int[] randomNumbers= new int[Maxsize];
for (int idx = 1; idx < Maxsize-1; ++idx){
randomInt = randomGenerator.nextInt(100);
randomNumbers[idx]=randomInt;
System.out.println("Random number: "+randomInt);
}
drawView = new DrawView(Graphic2D.this, randomNumbers, Maxsize);
drawView.setBackgroundColor(Color.WHITE);
setContentView(drawView);
}
}
package android.nacho.Graphic2D;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View {
Paint paint = new Paint();
int[] values;
int Size, Offset;
public DrawView(Context context, int[] datainBytes, int size) {
super(context);
values=datainBytes;
Size=size;
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
int cont2;
for(int cont=0; cont<Size-(1); cont++)
{
cont2=cont+1;
canvas.drawLine(cont, 500-(values[cont]) , cont+1, 500-(values[cont2]), paint);
}
}
}
The thing is, now I want to dram much more points, but in a dinamicall way so the new value is the one most at the right, the rest of the values move one pixel to the left and the one most of the left just don't appear. I was planning to this with a loop in the main Activity, so in each iteration the random values are all the same but the last one, and the others have move one position to the left in the array. The final effect should be something like a video.
But there is a problem, do App don't draw this dinamically, it just draw the last iteration of the loop. ¿Could anyone help me to solve this?
I was thinking in using AsyncTask for that, doing the points generation in the backgroun and sending the result to the update so draw in, but the script was a mess that didn't work, so I prefer to don't upload it.
Thank you very much for any suggestion.
I have one activity in my Android App for now which is a RelativeLayout with a background color and onCreate I create a number of random colored circles and addViews on to the relativelayout based on the device screen width and height. Here are the code snippets.
MyActivity.java
package com.myapp.android;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.view.Display;
import android.widget.RelativeLayout;
public class MyActivity extends Activity {
/** Called when the activity is first created. */
Random randomGenerator = new Random();
String[] colors = { "#84B62C", "#6A28F2","#F3FA0A", "#DF1FE4", "#0000A0", "#28C9DB", "#E05323"};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
RelativeLayout main = (RelativeLayout) findViewById(R.id.main_myapp);
// Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
int number_side = width / 100;
int number_down = height / 100;
for(int i = 0; i < (number_side * number_down) * 3; i++) {
main.addView(new Ball(this,randomGenerator.nextInt(width), randomGenerator.nextInt(height), 40 * (randomGenerator.nextInt(3)), colors[randomGenerator.nextInt(colors.length)], "BALL" + Integer.toString(i)));
}
}
}
This works great draws all the colored circles in random throughout the screen as I want it. Looks good. Here is the code for the Ball.java where the circles are drawn.
Ball.java
package com.myapp.android;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.View;
import android.widget.RelativeLayout;
public class Ball extends View {
private final float x;
private final float y;
private final int r;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
public Ball(Context context, float x, float y, int r, String color, String tag) {
super(context);
mPaint.setColor(Color.parseColor(color));
this.x = x;
this.y = y;
this.r = r;
this.setTag(tag);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
}
What I am trying to do is let the user touch any one of the colored circle and drag it on the screen wherever they want to but I cannot get them to move. I have not posted any trial code here.
What would be the best way to detect the user touch (this can be onTouch or onLongClick) on any of the circles drawn on screen (one circle at a time especially the one that is touched by the user) and thereafter make the circle (which is essentially a view added to the main Relative Layout View group at run time) to follow the users touch drag action (ACTION_MOVE - my guess) until they release the drag (ACTION_UP - my guess).
I have read some tutorials on this topic but none has been really helpful or applicable to my use case. Also I wanted to ask you knowledgeable guys should I use the 2D Graphics Canvas or OpenGL API in my case so that the drag operation on the circles are very smooth and instantaneous. Feel free to run my simple code, it works fine until the balls are drawn on the screen.
In your implementation, you consider Ball as a View and there are many balls thus there are many Views.
If I were you, I'll consider the whole screen is ONE View and the balls are only sprites inside that View.
Say, I'll extend the View class or SurfaceView class and have a Collection as attribute to store all coordinates and sizes of balls. Inside onDraw(), it should loop through the collection and draw the balls on correct location with correct size.
I am developing a Car Race Game. I am able to move, stop, accelerate. But i want that when i press screen then car(bitmap of car image) should look like, it had jumped on its place.I am using surfaceviewto draw view
I do not want to use 3D openGL. Any help is much appreciated
finally i used.On touch event, i create a bigger bitmap and draw it on same place. So it will give zoom effect
Bitmap bitmapToZoom; // Create a Bitmap
// Now zoom it
bitmapToZoom=Bitmap.createScaledBitmap(bitmapToZoom, bitmapToZoom.getWidth()+30,bitmapToZoom.getHeight()+30, null);
//now draw it again
canvas.drawBitmap(bitmapToZoom, 0,0,null);
So now finally, Zooming actor on touch code will be like this. Class Name ZoomonTouc.java
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.RectF;
import android.view.MotionEvent;
import android.view.SurfaceView;
public class ZoomonTouc extends SurfaceView {
public Bitmap mMyChracter;
public ZoomonTouc(Context context) {
super(context);
mMyChracter = BitmapFactory.decodeResource(context.getResources(),
R.drawable.ic_launcher);
setWillNotDraw(false);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mMyChracter, mMyChracter.getWidth()/2, mMyChracter.getHeight()/2, null);
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
RectF rectF = new RectF(mMyChracter.getWidth()/2, mMyChracter.getHeight()/2, mMyChracter.getWidth() + 100,
mMyChracter.getHeight() + 100);
if (rectF.contains(event.getX(), event.getY())) {
mMyChracter = Bitmap.createScaledBitmap(mMyChracter,
mMyChracter.getWidth() + 10, mMyChracter.getHeight() + 10,
false);
}
return true;
}
}
To test it properly create one activity and set above surface to activity background
setContentView(new ZoomonTouc(this));
I am using RelativeLayout to position views at precise locations on the screen. This works as expected when using a view that say, draws a rectangle. But when using Android views like EditText, they are drawn shorter than specified by about 8 units. Clicking outside of the drawn EditText (but within the parameters specified by RelativeLayout) will, in fact, hit the EditText.
Here is some code to illustrate what I mean:
package com.DrawDemo;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.RelativeLayout;
public class DrawDemo extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
RelativeLayout l = new RelativeLayout(this);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(100,100);
lp.leftMargin = 50;
lp.topMargin = 50;
DemoView demoview = new DemoView(this);
l.addView(demoview, lp);
EditText editText = new EditText(this);
l.addView(editText, lp);
setContentView(l);
}
private class DemoView extends View
{
public DemoView(Context context)
{
super(context);
}
#Override protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.GREEN);
canvas.drawPaint(paint);
}
}
}
If you execute this, you will notice that the EditText is noticeably shorter than the rectangle. I've tried mucking with onMeasure, setMinimumXXX, and just about everything else I can think of. So far, the only thing that works with some level of success is to just add 8 or so pixels to the height (8 seems to work better than trying a percentage of the height).
Next task will be to step into the source but was wondering if somebody has already solved this.
Thanks.
It's just because of the actual EditText background image that's used. Buttons are the same way, for some reason Google decided to draw the 9-patch background images with some extra transparent padding pixels. Really, the only solution, if it's a problem, would be to draw your own 9-patch, or modify the existing Android 9-patch to remove the extra pixels.