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.
Related
I wrote the following code and it works well. But I have other purpose. I want to click only on a view to doing the operations.First, Please see the following image:
MY CODE IS AS FOLLOWS:
public class MainActivity extends Activity {
RelativeLayout relativeLayout;
#Override
protected void onCreate(Bundle bundle)
{ super.onCreate(bundle);
relativeLayout = new RelativeLayout(getApplicationContext());
setContentView(relativeLayout);
A a = new A(this);
relativeLayout.addView(a);
a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
B b = new B(getApplicationContext());
relativeLayout.addView(b);
}
});
}
}
class A extends View {
Paint paint;
A(Context context) {
super(context);
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas) {
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawRect(20,60,100,150,paint);
}
}
class B extends View {
Paint paint;
B(Context context){
super(context);
paint = new Paint();
}
#Override
protected void onDraw(Canvas canvas){
paint.setAntiAlias(true);
paint.setColor(Color.GREEN);
canvas.drawRect(100,150,200,250,paint);
}
}
when I run the above code I can see the green rectangle after press on the red rectangle. But the problem is that when I press another places on the screen I can do this operations also. I want that only I can see the green rectangle to press on the red rectangle and not in the another places on the screen to doing this operations.
Use onTouch event
a.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getX(0)>=20 && event.getY(0)>=60 && event.getX(0)<=160 && event.getY(0)<=150) {
B b = new B(getApplicationContext());
relativeLayout.addView(b);
}
return true;
}
});
You are defining the red square's parameters but not the parameters of the canvas in which you are drawing. You are creating the view (A) without defining the width and height of it, so it is set to match_parent by default, which means it will take the whole size of your RelativeLayout (the whole screen). So, when you click "outside" the red square you are actually clicking the view (A).
Try to define an specific height and width for the view in which you are drawing, like this.
A a = new A(this);
a.setLayoutParams(new RelativeLayout.LayoutParams(300,300));
Remember that LayoutParams takes pixels as parameters, so you should really convert the dps to px as specified here
Also, setting some background colors to your views (relativeLayout, A) will help you visualize what you are doing.
# nukeforum, your guess helped me very much. I thank all of you. My problem was exactly from the canvas and its size. I added the following operation in my code and solved my problem.
relativeLayout.addView(a,70,70);
For A class, I changed as follows:
canvas.drawRect(10,20,30,40,paint);
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.
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.
I have read the following links:
How to draw a line in android
http://marakana.com/s/android_2d_graphics_example,1036/index.html
http://developer.android.com/reference/android/graphics/Canvas.html
Activity.setContentView, View.setContentView?
How to create an activity without 'setContentView(R.layout.main)'
http://www.jayway.com/2009/03/26/layout-resources-in-android/
I have read the previous articles that talk about about my problem but I can't solve my problem.
My problem is that I want to draw straight lines to simulate the connection between images, but basically is to paint straight lines.
All the examples I've seen have the main class that inherits from the activity and have another inner class that inherits from the View. And in the main class set the user interface that contains the View class, so we have a empty user interface.
Something like this:
public class ActivityMain extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyView view1 =new MyView(this);
setContentView(view1);
}
public class MyView extends View {
public MyView(Context c) {
super(c);
}
}
//And more code
}
I want to set my user interface (xml file) in the class that inherits from the activity (as usual):
public class ActivityMain extends Activity{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.union);
}
}
And I want from the class that inherits from activity to draw straight lines, I don't want to have any class that inherits from View.
I tried the following but I don't see any line:
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
Canvas canvas = new Canvas();
Paint paint = new Paint();
paint.setColor(Color.BLACK);
canvas.drawLine(0, 0, 300, 700, paint);
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
In the previous method I want to draw a line from the corner 0,0 to the corner 300,700. It's a simple test. But I don't draw anything and I don't know why.
You can extend a view and override the onDraw and manage all your lines there.
Then, you can add this view (that can be full screen) in another xml (that can be used in an Activity) like this:
<my.package.myView
android:layout_width=#"fill_parent"
android:layout_height=#"fill_parent"/>
Be sure that the layout you use in your main activity is a RelativeLayout so you can fill the entire screen AND be on the top of your views. To place your view on top of your views be sure that you have your view in the end of your activity xml.
so i created a view called "drawable view"
class DrawableView extends View{
Context mContext;
int touches=0,k,Xoffs,clicks=0;
double x_1 = 0,x_2=0;
private float mLastTouchX, mLastTouchY;
public DrawableView(Context context) {
super(context);
mContext = context;
}
....
#Override
protected void onDraw(Canvas canvas){
Paint myPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
canvas.drawColor(Color.BLUE);
myPaint.setColor(Color.WHITE);
canvas.drawCircle(200, 100, 20, myPaint);
}
..... more code....
}
and it can only be invalidated within the ondraw command! ie: calling "invalidate();" at the end of the ondraw command causes it to loop.
I have tried many times to call g_draw.invalidate(); or g_draw.postInvalidate(); (g_draw is the name of the created Drawable View)from other classes and even the main activity class and it doesnt work. why and how can i fix it?
thanks
If you want continious onDraw invoking try doing it in another thread. Create a thread, and from its run method try doing postInvalidate.
It always worked for me.
Another thing is that when you draw a circle once, next time wont make any difference - it will look the same.
You may want to call invalidate() somewhere in your DrawableView class. For example, if you want your view to redraw itself after any touch event, you would do something like this:
public boolean onTouchEvent( MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP){
invalidate();
}
}
This is how I draw the movable pieces in my puzzle game.