I am new to android and I have an image in my drawable folder which I was able to load as my background, now I would like to draw on top of the background but havent been able to, how can achieve this... I have the following, all i want is to draw a circle on top of the image background
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="#+id/my_view"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/background">
</FrameLayout>
//MY ACTIVITY
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
//IN MY VIEW CLASS
public GameView(Context context, float x, float y, int r) {
super(context);
setFocusable(true);
mPaint.setColor(Color.YELLOW);
this.x = x;
this.y = y;
this.r = r;
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawCircle(x, y, r, mPaint);
}
To set the image as background use ImageView in Absolute Layout.Enter code to set img as background :
android:background="#drawable/icon1"
Now you would be able to have circle over the image view
use ImageView in xml file & set what u want to draw on background.
Related
I want to create a layer with transparent layer over an activity and I need to make visible only a particular view, say for an example "Login Button". It something mean that making hole on layer exactly the size of the button. Please anyone help me out of this.
Thanks In advance.
Programatically, you can use Canvas to create a layer. Fill the whole thing with your color and cut out a hole.
public class DrawView extends View {
Paint paint = new Paint();
Paint transparentPaint = new Paint;
public DrawView(Context context) {
super(context);
}
#Override
public void onDraw(Canvas canvas) {
//first fill everything with your covering color
paint.setColor(yourTransparentColor);
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
//now clear out the area you want to see through
transparentPaint.setAlpha(0xFF);
transparentPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
Rect rect=new Rect(left, top, right, bottom);//make this your rect!
canvas.drawRect(rect,transparentPaint);
}
}
If I understand your question correctly
Your parent Layout of the Activity will be a RelativeLayout. In your parent layout at the bottom add another child RelativeLayout that implments the match_parent parameters for both width and height. You can then set a color like this #99000000 to it's background. This will give you a black transparent layer over your parent.
Something like this
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/parentLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<!-- here you add your activities views ect... -->
<RelativeLayout
android:id="#+id/childLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#99000000">
<!-- This will be your overlay so here you can add your login button ect -->
</RelativeLayout>
</RelativeLayout>
I didn't test this but it should solve your issue
On following "HalR" Steps , I was able to achieve the transparent background Thanks to him and found some of you are getting pitch black on the cut made over transparent layer is due to Graphic rendering . that can be enabled using below code inside onDraw method
` #Override
public void onDraw(Canvas canvas) {
if (android.os.Build.VERSION.SDK_INT >= 11) {
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
.....
..... // your draw rect creation and other stuff `
which will let you have the transparent area by eliminating the Pitch black color
If i understood your question then this is what you wanted:
You tried to overlay a transparent view on your activity and cut out holes to see few stuffs.
here i found an useful example which shows how can you cut out bitmaps and combine them. i would suggest for your problem just take the part of cutting the bitmap and remember to set the imageview backgroung with opacity as shown here
android:background="#00ffffff"
here is the layout i created
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/ic_launcher"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"/>"
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ffffff"
android:scaleType="centerCrop" >
</ImageView>
</RelativeLayout>
and this is my maniactivity
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv = (ImageView) findViewById(R.id.img);
Bitmap foreground = BitmapFactory.decodeResource(getResources(), R.drawable.android_cat_wanted);
foreground = punchAHoleInABitmap(foreground);
iv.setImageBitmap(foreground);
}
private Bitmap punchAHoleInABitmap(Bitmap foreground) {
Bitmap bitmap = Bitmap.createBitmap(foreground.getWidth(), foreground.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
canvas.drawBitmap(foreground, 0, 0, paint);
paint.setAntiAlias(true);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
float radius = (float)(getScreenSize().x *.35);
float x = (float) ((getScreenSize().x*.5));
float y = (float) ((getScreenSize().y*.5));
canvas.drawCircle(x, y, radius, paint);
return bitmap;
}
#SuppressLint("NewApi")
private Point getScreenSize() {
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
return size;
}
}
hope you find it useful
i try to draw vertical lines in android.
DrawView drawView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
drawView = new DrawView(this);
setContentView(drawView);
}
public class DrawView extends View {
Paint paint = new Paint();
public DrawView(Context context) {
super(context);
paint.setColor(Color.RED);
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawLine(0, 100, 0, 0, paint);
}
}
What this draw just one line. What i want to do draw this lines in whole screen. How can i do that? It must draw everywhere in screen vertically. It now draws vertically but just one.
So far from your desired use case, I don't see any reason for you to use a custom view for this. You can set a custom background with repeat enabled:
res/drawable/MyBackground.xml
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="#drawable/lines_image"
android:tileMode="repeat" />
Then for your view, set the background:
res/layout/whatever.xml
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/MyBackground" />
OR
myView.setBackgroundResource(R.drawable.MyBackground);
lines_image.png should be a 20px (or however much space between you want) wide image with your red line on the right.
It's an important concept for UI development. Don't do complicated things in code when a simple image solution will suffice.
If you absolutely **MUST** Do this in code, Then you just do the drawing in a loop for the width of the canvas.
private static final int LINE_SPACING = 20;
#Override
public void onDraw(Canvas canvas) {
for (int x = 0; x < canvas.getWidth(); x += LINE_SPACING) {
canvas.drawLine(x, 0, x, canvas.getHeight(), paint);
}
}
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'm extending ImageView in order to manually scale an image within the view. I want to scale an image to fill the width of the custom view, and then draw it to the canvas, however, I'm unable to get the view width using this.getWidth()
It just returns 0, as the view has not yet been drawn and so has dimensions 0 by 0.
Currently I have the following in my main.xml:
<com.android.myapp.BackgroundView
android:id="#+id/background_view"
android:layout_height="fill_parent"
android:layout_width="fill_parent"
android:src="#drawable/background"
android:dither="true"
/>
The custom class is as follows:
public class BackgroundView extends ImageView {
private Paint paint;
private Bitmap background;
public BackgroundView(Context context) {
super(context);
paint = new Paint();
loadBitmap();
}
public BackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
loadBitmap();
}
public void loadBitmap() {
BitmapDrawable src = (BitmapDrawable) this.getDrawable();
background = src.getBitmap();
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(background, 0, 0, paint);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
My Main.java class is:
public class Main extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
I can't use
Bitmap.createScaledBitmap(background, view.getWidth(), view.getHeight(), false)
as the view hasn't yet been drawn, how would I go about scaling the image to fill the view/screen width at this point?
Thanks in advance.
I believe what you want to do could also be achieved by using ImageView directly in conjunction with the scaleType attribute. Either use fitXY or centerCrop, depending on your needs.
But to answer the question, you can only use getWidth() and getHeight() after layout() has been called. So you should be able to use the values inside your onDraw method.
Also you could use another drawBitmap method so you wouldn't have to create a new bitmap in memory.
I am trying to make a thermometer. For this I have an image of a thermometer(a png file) which i have inserted
into the layout using ImageView. Now I want to draw a line over this image to show the effect of temperature reading.
Here is my code.
main.xml
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ImageView
</ImageView>
<com.focusone.Android.DrawExample.CustomDrawableView
android:id="#+id/custom_drawable_view"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
height='100'
/>
</AbsoluteLayout>
DrawExample.java
package com.focusone.Android.DrawExample;
public class DrawExample extends Activity {
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
CustomDrawableView.java
public class CustomDrawableView extends View {
private ShapeDrawable mDrawable;
public CustomDrawableView(Context v,AttributeSet as){
super(v,as);
drawShape(as);
}
public void drawShape(AttributeSet ast) {
int x =45; int y=15 ; int width=5; int height=0 ;
height= Integer.parseInt(ast.getAttributeValue(null, "height"));
mDrawable = new ShapeDrawable(new RectShape());
mDrawable.getPaint().setColor(0xff74AC23);
mDrawable.setBounds(x, y, x + width, y + height);
}
protected void onDraw(Canvas canvas) {
mDrawable.draw(canvas);
}
}
Now I can draw a line on top of the thermometer image using this program.
But how do i change the height of line during runtime.
Since height=100 is written in the xml file I don't know how I can change it.
Please somebody help me.
First I think you don't need to pass attributes in drawShape(AttributeSet ast) but just height in your constructor CustomDrawableView(). Then as Chris said you should have another method in the custom view like
public void setTemperature(int tmp){
drawShape(tmp);
invalidate(); //this will call onDraw()
}
In your main activity make a reference to your custom view so you can call its public methods
CustomDrawableView temperatureView =
(CustomDrawableView) findViewById(R.id.custom_drawable_view);
temperatureView.setTemperature(50);
You can:
Make "height" a member of your CustomDrawableView
Then create a method setHeight(int height) where you change the value of height.
Then in your activity use (CustomDrawableView)findViewById(R.id.custom_drawable_view) to get a reference to your viewObject.
Then change the value as you like with calling setHeight(x)
hope that helps