How to work with the X,Y Coordinates in android - android

I am new to android and I am trying with positioning my drawings at the right coordinate using touch screen. When i touch the screen I obtain the coordinates(x,y) but when i press my button to draw the circle it draws the circle at a location below the point i touched.I am using a relativeLyout as my layout, and i gave it an ID as "Layout" which I use to reference it in my java class.I thought it is because i am using the addView to draw on the same layout.I tried all my best to correct it but could not. (THE CIRCLE IS DRAWN AFTER CLICKING THE BUTTON BUT NOT AT THE POSITION I WANT IT, IT GOES BELOW THE POINT I TOUCHED)Can someone please help me.
Here is my code.
public class MyView extends View{
float x ;
float y ;
int radius = 20;
public MyView(Context context, float x, float y){
super(context);
this.x = x;
this.y = y;
} //end constructor
public void onDraw(Canvas canvas){
Paint paint = new Paint();
paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
canvas.drawCircle(x, y, radius, paint);
} //end onDraw
} //end class MyView
Here is my MAIN CLASS:
public class ButtonClickActivity extends Activity implements OnClickListener{
RelativeLayout laying;
Button button;
MyView myView;
private static float x=100;
private static float y=100;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_button_click);
laying = (RelativeLayout) findViewById(R.id.layout);
button = (Button) findViewById(R.id.circle);
//set listeners
button.setOnClickListener(this);
} //end onCreate
public void onClick(View view){
switch(view.getId()){
case R.id.circle:
myView = new MyView(this, x, y);
laying.addView(myView);}
Here is the Touch event
public boolean onTouchEvent(MotionEvent event){
int action = event.getAction();
//get the type of action
switch(action){
case MotionEvent.ACTION_DOWN: //you have touch the screen
x = event.getX();
y = event.getY();
break
}
}
Here is the Layout
<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"
android:layout_gravity="center"
android:id="#+id/layout" >
<Button
android:id="#+id/circle"
android:layout_alignParentBottom="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight = "1"
android:text="Circle"/>
</RelativeLayout>

What you miss is the size of the view. Your custom view doesn't know how much space it needs for the circle, and the default one is wrap content, so what is the minimal size? That's right: 0.
That's why you can't see anything. Either you set a size from outside of the view, or you measure it somehow yourself within the view and tell the parent view what size the view needs (and then check what the parent gives you and use it).
Read here for more information about custom views.
Incidentally, it's not recommended to create the paint inside the onDraw, at least not in a way that recreates it each time it's called.

Related

Android library overlay rectangle disappears

I have a library that shows a camera preview. I want to add a rectangle overlay on top of the preview. I tried 2 different approaches. But both of them display the rectangle shortly then disappear.
approach (using view.getOverlay)
mPreview.setZOrderMediaOverlay(true);
mPreview.setZOrderOnTop(true);
ViewGroup rootView = (ViewGroup)mActivity.getWindow().getDecorView().findViewById(android.R.id.content);
rootView.addView(mPreview);
final ViewOverlay overlay = mPreview.getOverlay();
final Bracket bracket = new Bracket();
mPreview.post(new Runnable() {
#Override
public void run() {
bracket.setBounds(0, 0, mPreview.getWidth(), mPreview.getHeight());
overlay.add(bracket);
}
});
approach (overriding draw function in surfaceview)
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GREEN);
paint.setStrokeWidth(10);
//center
int x0 = canvas.getWidth()/2;
int y0 = canvas.getHeight()/2;
int dx = canvas.getHeight()/3;
int dy = canvas.getHeight()/3;
//draw guide box
canvas.drawRect(x0-dx, y0-dy, x0+dx, y0+dy, paint);
}
mPreview extends SurfaceView
Bracket extends Drawable
UPDATE
If I use setContentView instead of rootView.addView it works as expected. But in this case I can not remove the view.
I used a new Activity and setContentView. That solved the problem.
To remove the view I finished the action.

How to draw multiple bitmaps on canvas?

I want to develop a game that shoots bullets on every touch of the canvas.
It works but when I touch the canvas after shooting, he takes the bullet and restarts the shooting.
I just want the bitmap to create new bullet at every touch. Here is my code:
public class MainActivity extends Activity implements OnTouchListener {
DrawBall d;
int x ;
int y;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
d = new DrawBall(this);
d.setOnTouchListener(this);
setContentView(d);
}
public class DrawBall extends View {
Bitmap alien;
public DrawBall(Context context) {
super(context);
alien = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
startDraw(canvas);
}
public void startDraw(Canvas canvas){
Rect ourRect = new Rect();
ourRect.set(0,0, canvas.getWidth(), canvas.getHeight());
Paint blue = new Paint();
blue.setColor(Color.BLACK);
blue.setStyle(Paint.Style.FILL);
canvas.drawRect(ourRect, blue);
if(y < canvas.getHeight()){
y-=5;
}
canvas.drawBitmap(alien, x, y,new Paint());
invalidate();
}
}
public boolean onTouch(View v, MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
return false;
}
}
I only superficially read the code. It seems that you are only keeping track of one bullet using the x y coordinates.The coordinates are resetting at every touch event, and thus you lose the previous bullet.
Use a dynamic array, or a linked list to keep track of all the bullets on the screen.
When there's a new touch, add the x,y to the array.
When drawing the bullet, iterate through your array to draw and update every bullet.
If the y-coordinate of any bullet goes out of the screen, delete the bullet from the array.
Each draw starts with a blank canvas. So to draw multiple bitmaps you need to keep track of where to draw each bullet and call drawBitmap multiple times.
Also, calling invalidate in onDraw is a bad idea- it will immediately invalidate, leading you to have performance issues. I'd suggest invalidating on a timer instead. Drawing too frequently will lead to performance issues.

Android- Draw line between two views

Below is my program where I have created three new views in a frame. On click of two different views I want to draw a line between the views. I am trying to figure out how to do this...
Ball ball1=new Ball(this,100,100,45);
Ball ball2=new Ball(this,400,100,45);
Ball ball3=new Ball(this,250,350,45);
FrameLayout frame1=(FrameLayout) findViewById(R.id.main_view);
frame1.addView(ball1);
frame1.addView(ball2);
frame1.addView(ball3);
frame1.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()){
case MotionEvent.ACTION_DOWN: {
float x = event.getX();
float y = event.getY();
System.out.println("x:"+x+"y:"+y);
if (x>55 && x<142 && y>55 && y<142)
{
System.out.println("working1 "+count);
Toast toast = Toast.makeText(getBaseContext(), "Works fine", Toast.LENGTH_SHORT);
toast.show();
}
For a draw line between your two views.
Create class for view which draw a line.
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawLine(0, 50, 350, 50, paint);
}
}
now from your activtiy where you want to add this line in your layout.
Create object of this class and add this view in your layout.
According to your requirment try like this.
DrawView drawView;
drawView = new DrawView(this);
frame1.addView(ball1);
// add that view here
frame1.addView(drawView);
frame1.addView(ball2);
// same way here
frame1.addView(ball3);
Just draw line in onDraw() on some condition and set this condition in your activity in onTouch() method. Then call invalidate on Views that you changed their condition.

Android clickable map image

I am creating an app which is going to have as a background USA map. I want to click on the map and wherever I click I want to create a small red dot. But it should not be created outside of the map borders. Can I use GridView? Thanks.
You can just create a Linear Layout with a USA map as the background and then set an onTouchListener to that Linear Layout, inside the onTouch just add a red dot on the x and y coordinates that the person clicked. Something like this:
public class MyAppActivity extends Activity {
LinearLayout mLayout;
double x, y;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mLayout = (LinearLayout) findViewById(R.id.yourID);
mLayout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
x = event.getX();
y = event.getY();
//Draw a ball using the x and y coordinates. You can make a separate class to do that.
return false;
});
}
}
and your xml could look something like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/yourID"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/yourUSABackGround"
>
</LinearLayout>
Hope that helps.

How-to create a clickable Button with a ShapeDrawable?

I'm trying to draw a shape on a Canvas and get information about the clicks that the user performs on that Canvas.
I created a class which extends the Button class.
class CustomDrawableButton extends Button {
private final ShapeDrawable mDrawable;
int x = 50;
int y = 50;
int width = 30;
int height = 30;
public CustomDrawableButton (Context context) {
super(context);
mDrawable = new ShapeDrawable (new OvalShape ());
mDrawable.getPaint().setColor(Color.GREEN);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
Then, in a class which also extends View, I added the instantiation and a listener:
CustomDrawableButton mCustomDrawableButton = new CustomDrawableButton(getBaseContext());
layout.addView(mCustomDrawableButton);
mCustomDrawableButton.draw(canvas);
mCustomDrawableButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
System.out.println("Yey clicked");
Toast.makeText(view.getContext(), "Yey", Toast.LENGTH_LONG).show();
}});
When this is executed, it is not able to detect the clicks on the image / button. I have read that ShapeDrawable objects can't be "clickable", but I was expecting this to work since I'm extending the Button (which is a View and is "clickable").
Is this possible? If not this way, can you direct me to some way to get information about the screen coordinates that were pressed on a Canvas or a View ?
Thanks in advance.
After some searching here's a tutorial that shows how to do it using by getting the touched screen position.
http://marakana.com/tutorials/android/2d-graphics-example.html
Still don't know how to do it by automatically binding the touched event to a button. If anyone knows how to do it, please say so.
Thanks.

Categories

Resources