I want to generate Rectangle on same size but at random positions on an ImageView. When I click the button the position of the rectangle must change
I have attached the entire Activity. First, I open an image from the gallery and draw a rectangle on it. When the shuffle button is clicked, it has to move
public class Register extends Activity {
ImageView img;
String picpath;
Bitmap bmp;
Canvas cnvs;
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.register);
img=(ImageView)findViewById(R.id.imageView1);
//Open Button
Button open=(Button)findViewById(R.id.button3);
open.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent gal_open=new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(gal_open,1);
}
});
Button shuffle=(Button)findViewById(R.id.button2);
shuffle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
int height=img.getHeight();
int width=img.getWidth();
int x;
int y;
Random r=new Random();
x=r.nextInt(width)*width;
y=r.nextInt(height)*height;
Paint paint=new Paint();
cnvs.drawBitmap(BitmapFactory.decodeFile(picpath), 0, 0, null);
cnvs.drawRect(x, y,x+50,y+50 , paint);
img.setImageBitmap(bmp);
}
});
}
public void onActivityResult(int requestCode,int resultCode,Intent intentData)
{
super.onActivityResult(requestCode, resultCode, intentData);
if(requestCode==1 && resultCode==RESULT_OK && intentData!=null)
{
//ImageView img=(ImageView)findViewById(R.id.imageView1 );
Bitmap bmp=Bitmap.createBitmap(img.getHeight(),img.getWidth(),Bitmap.Config.RGB_565);
Canvas cnvs=new Canvas(bmp);
Paint paint=new Paint();
paint.setColor(Color.RED);
Uri data=intentData.getData();
String[] filePath={MediaStore.Images.Media.DATA};
Cursor cur=getContentResolver().query(data,filePath,null,null,null );
cur.moveToFirst();
int colIndex=cur.getColumnIndex(filePath[0]);
picpath=cur.getString(colIndex);
cur.close();
cnvs.drawBitmap(BitmapFactory.decodeFile(picpath), 0, 0, null);
cnvs.drawRect(20, 20,50,50 , paint);
img.setImageBitmap(bmp);
//cnvs.drawRect(20, 20,50,50 , paint);
}
}
}
Please consider this:
//drawRect (float left, float top, float right, float bottom, Paint paint)
in your case it would never change the position as its starting point would always be same you need to change that also. I think this is the case you are getting wrong values in X,and Y . Also try to give the range to the Random generator like 1 to 60
You can simply change the values of X and Y like
x=r.nextInt(width);
y=r.nextInt(height);
but make it sure it should not go beyond the bounds of bitmap
x=r.nextInt(width) will already give you 0 <= x < width, so you shouldn't multiply it again by width.
Same for y and height.
Also, where is your cnvs coming from ? I'm not sure you can just draw on your ImageView in the onClick. I would have made a custom ImageView which remembers where the rectangle is supposed to be and draw it in its onDraw method, then during the onClick, method I would change the variables that store the rectangle position and force a redraw (so onDraw will draw the rectangle at the new position).
Create Random r as a class member and initialize it in the onCreate() method and not as Random r=new Random() inside the onClick()
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'm trying to create an app that has a fairly complex UI.
I'm trying to understand what is the best practice to render irregular button shapes to the screen.
I'm adding this image as an example. Each one of these wooden boards is a button.
I obviously can't use Android's Button or ImageButton because the shape is not a rectangle.
I assume I need to draw this directly onto a canvas or use onDraw or Draw to make this happen.
Is this the correct way I should use to render these as buttons?
Any good reading material on these is HIGHLY appreciated..
Thank you
You can create a customized View working in following way:
in onDraw() paint 3 bitmaps each representing single button (where 2 other buttons are transparent),
in onTouch() check the touched pixel against those bitmaps to see which bitmap was clicked
Code snippet:
public class DrawingBoard extends View {
Bitmap mBitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.button1);
Bitmap mBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.button2);
Bitmap mBitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.button3);
public DrawingBoard (Context context) {
// TODO Auto-generated constructor stub
super (context);
}
#Override
protected void onDraw (Canvas canvas) {
canvas.drawBitmap(mBitmap1, 0, 0, null);
canvas.drawBitmap(mBitmap2, 0, 0, null);
canvas.drawBitmap(mBitmap3, 0, 0, null);
}
#Override
public boolean onTouchEvent (MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN :
int xx = (int)event.getX();
int yy = (int)event.getY();
if(Color.alpha(mBitmap1.getPixel(xx,yy)) != 0) {
// button1 pressed
}
else if(Color.alpha(mBitmap2.getPixel(xx,yy)) != 0) {
// button2 pressed
}
else if(Color.alpha(mBitmap3.getPixel(xx,yy)) != 0) {
// button3 pressed
}
break;
}
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// bitmaps are assumed to be of the same size
setMeasuredDimension(mBitmap1.getWidth(),mBitmap1.getHeight());
}
}
I didn't test the code, it it may have errors.
A variant - you can create a virtual bitmap storing 'hit codes' for pixels on whole image. You can create it from original picture but replace pixels with ids to detect which area was touched, all other pixels make 'empty' (0x0). So getPixel() will return id of a button.
I am new Android programming.
I am trying to open an image from the Gallery of a phone and draw a Rectangle on top of the image I have opened. But I am able to open the image but I am not able to see the rectangle. I am using ImageView and Canvas to open image and draw. I have created a Button and used to image from Gallery. I have written the code to open and draw in onActiviesult() method.Could somebody help me?!. Thanks in advance
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button gal=(Button)findViewById(R.id.button1);
gal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent gal_open=new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(gal_open,1);
}
});
}
public void onActivityResult(int requestCode,int resultCode,Intent intentData){
super.onActivityResult(requestCode, resultCode, intentData);
if(requestCode==1 && resultCode==RESULT_OK && intentData!=null){
ImageView img=(ImageView)findViewById(R.id.imageView1 );
Bitmap bmp=Bitmap.createBitmap(img.getHeight(),img.getWidth(),Bitmap.Config.RGB_565);
Canvas cnvs=new Canvas(bmp);
//img.setImageBitmap(bmp);
Paint paint=new Paint();
paint.setColor(Color.RED);
Uri data=intentData.getData();
String[] filePath={MediaStore.Images.Media.DATA};
Cursor cur=getContentResolver().query(data,filePath,null,null,null );
cur.moveToFirst();
int colIndex=cur.getColumnIndex(filePath[0]);
String picPath=cur.getString(colIndex);
cur.close();
cnvs.drawRect(20, 20,50,50 , paint);
img.setImageBitmap(bmp);
img.setImageBitmap(BitmapFactory.decodeFile(picPath));
}
}
return super.onOptionsItemSelected(item);
}
}
try drawing the bitmap on the canvas and then call setImageBitmap just once. In this moment you are overriding the content of the ImageView. Remove img.setImageBitmap(BitmapFactory.decodeFile(picPath));
and
cnvs.drawBitmap(BitmapFactory.decodeFile(picPath), 0, 0, null);
cnvs.drawRect(20, 20,50,50 , paint);
img.setImageBitmap(bmp);
I am not sure abaut the drawing order. If you don't see the rectangle try changing the order of drawRect and drawBitmap
You may try like this way which i use:
create customborder.xml file.
Just take imageview in layout and make border xml file
and now use this customborder in layout backgourd like:
android:layout_height="fill_parent"
android:background="#drawable/customborder">
In my application,I am setting an image in my imageview. I just need to place a marker on that imageview. I am doing it with onDraw function in my custom image view class.The problem is,for example if I take x position and y position as 40 respectively.The marker position shown above image in my mobile is different when compared with running same application on tablet.
I want a solution such that when I give coordinates then the position of marker on image in mobile and tablet appears same.
Here is the code my main activity:
public class PointOnImageActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_point_on_image);
CustomImag ev= new CustomImag(this);
ev.setBackgroundResource(R.drawable.stad);// set background
setContentView(ev);
}
}
Here is the code of my custom imageview class:
public class CustomImag extends ImageView
{
public CustomImag(Context context)
{
super(context);
}
#Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint mPaint = new Paint();
mPaint.setColor(Color.RED);
canvas.drawCircle(40,40,10,mPaint);
}
}
that's because 40 is pixel value, you actually need 40dp instead. so you can convert 40dp to px value dynamically, like this:
int pxValue1 = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, context.getResources()
.getDisplayMetrics());
int pxValue2 = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, context.getResources()
.getDisplayMetrics());
canvas.drawCircle(pxValue,pxValue,pxValue2,mPaint);
You have to position your custom View according to the screen dimensions. This way, no matter what size screen displays your app, your positioning will be relative.
In your onDraw(Canvas) method, you can get the screen dimensions and draw the circle using them. In the following example(which is mostly your code), I place the red circle at screen_width / 4 and screen_height / 4:
public class MyCustomImageViewActivity extends Activity{
CustomImag ev;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ev = new CustomImag(this);
ev.setBackgroundResource(R.drawable.stad);// set background
setContentView(ev);
}
public class CustomImag extends ImageView {
Paint mPaint;
public CustomImag(Context context) {
super(context);
mPaint = new Paint();
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
Point point = new Point();
getWindowManager().getDefaultDisplay().getSize(point);
mPaint.setColor(Color.RED);
canvas.drawCircle(point.x / 4, point.y / 4, 10, mPaint);
}
}
}
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.