I am drawing a rectangle in the canvas on the first attempt and again I am attempting to draw one more rectangle at a different position. When I finally add them to LinearLayout I see the only 2nd rectangle, the first rectangle is lost.
Bitmap place = Bitmap.createBitmap(400,800,Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(place);
DrawRect dr = new DrawRect();
dr.setLocation(10,10);
dr.draw(canvas);
dr.setLocation(10,80);
dr.draw(canvas);
ll.removeAllViews();
ll.addView(dr);
How do I make both the rectangles to be visible?
removeAllViews() will remove all view of LinearLayout.
You are adding view after removeAllViews() thats why you see 2nd rectangle only.
So remove thisll.removeAllViews(); line and run again.
I found the problem in the code, i should not use the same DrawRect object for drawing one more item, instead use the same but different DrawRect object does the magic.
Related
I have a custom LinearLayout class that overwrites its onDraw() method. It goes into each row of ListView, as shown in the third picture. Everything looks great until I scroll the listview upward. Then the dotted line rendered from drawLine() call gets drawn over LinearLayout that sits above ListView. This is strange because the orange rounded rectangles get drawn without this problem.
My custom LinearLayout does call "this.setWillNotDraw(false);" I tried calling "LinearLayout1.postinvalidate();" in the ListView's onScrollListener, but it fails to get the top LinearLayout to redraw. What can I do to prevent the lines from getting drawn on top of LinearLayout?
Had to resort to the following workaround:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Bitmap offScreenBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas offScreenCanvas = new Canvas(offScreenBitmap);
// do your drawings onto offScreenBitmap here
Paint offScreenPaint = new Paint();
offScreenPaint.setAntiAlias(true);
offScreenPaint.setFilterBitmap(true);
offScreenPaint.setDither(true);
canvas.drawBitmap(offScreenBitmap,0,0,offScreenPaint);
}
My code actually prepares offScreenBitmap at the beginning, because its contents are static and need to be drawn only once.
Currently I am writing a program that is supposed to add an image to a canvas and then add that canvas to a relative layout. The problem that I am having is that when I call this the layout is displayed but the canvas is not drawn on the layout.
canvas = (RelativeLayout) findViewById(R.id.canvasLayout);
imageCanvas = new Canvas();
mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageCanvas.drawBitmap(mainImage, 50, 50, null);
imageCanvas.drawColor(Color.BLACK);
canvas.draw(imageCanvas);
That is the code that is attempting to add the image to the canvas and then the canvas to the layout.
I am completely lost as to what to do to attempt to fix this.
The canvas.draw(imageCanvas) call you are using actually draws canvas (the RelativeLayout) onto imageCanvas (the Canvas object) - likely not what you were intending. There are several ways I would suggest to go about getting the drawable onto the RelativeLayout:
The first would be to create an ImageView, set it's image to your drawable, then add it to the layout. Depending on if you want the images to be added dynamically during runtime or not, you could actually do this in the xml graphic designer. This is probably the best way to go, as it gives you control over how large the image is, and how it gets scaled/cropped.
If you want to set a background to the layout, I believe you can actually set the Background attribute of the RelativeLayout directly to a drawable - this does not allow as much control over the scaling of the image though.
Finally, for complete control over how the RelativeLayout is draw, you can override the OnDraw method in any view. This method is called by the android system whenever it needs to refresh the view. If you do end up using this, creating a custom view class, which you then place in the RelativeLayout will probably work better.
canvas = (RelativeLayout) findViewById(R.id.canvasLayout);
imageCanvas = new Canvas();
mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageCanvas.drawBitmap(mainImage, 50, 50, null);
canvas.addView(imageCanvas);
The following will programmatically add an image to your layout from a bitmap resource which sounds like what you want to do. If you need to draw on top of that image, say, you would need to make a custom component by extending ImageView and overriding onDraw().
canvas = (RelativeLayout) findViewById(R.id.canvasLayout);
imageView = new ImageView(getApplicationContext());
mainImage = BitmapFactory.decodeResource(getResources(), R.drawable.image);
imageView.setImageBitmap( mainImage );
canvas.addView( imageView );
I have prepared a custom view. My view contains one alphabet which i have drawn using drawText in onDraw().Now i need to change this view to bitmap.
Here my OnDraw() is,
public void onDraw(Canvas canvas) {
drawText("A",100,200,mPaint);
}
I need to convert this view to bitmap...please help me...thanks in advance .
For those that already have their views set up and want a shorter solution than AutoCoders:
Bitmap result = Bitmap.createBitmap(dst.getWidth(), dst.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
dst.draw(c);
After this the Bitmap 'result' will contain your view.
'dst' is the View you want as a bitmap.
Bitmap viewCapture = null;
theViewYouWantToCapture.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(theViewYouWantToCapture.getDrawingCache());
theViewYouWantToCapture.setDrawingCacheEnabled(false);
In Android, the word “bitmap”, is a class that help us to work with images as a map of bits or an array of bits. This Bitmap class is very useful when we are working with graphics interfaces like Canvas or OpenGL.
Canvas, is another known class in Java, and is used to draw things. In Canvas we have control of all the pixels.
We need to have some variables initialized,
This is the Canvas we are going to draw in.
Canvas canvas = null
This is the layout we are going to use to create our view.
RelativeLayout relativeView ;
This is the background we are going to set in our view, we get it from a resource file (R.drawable.blackBgrnd). The BitmapFactory.decodeResource method is used to get a resource image and convert it in a Bitmap (we will use the Bitmap class). The object mContext (context) must be passed from the Activity we are working on.
Bitmap viewBgrnd = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.blackBgrnd);
We need another bitmap, to draw it on the canvas. We set the width and the height of this bitmap relative to the width and height we have created in our layout. Now this Bitmap is empty, but we are going to associate it with the canvas, so every time we draw in the canvas, it will be drawn in this bitmap object.
Bitmap returnedBitmap = Bitmap.createBitmap(relativeView .width, relativeView.height,Bitmap.Config.ARGB_8888);
First of all, we had the canvas = null, now we create a Canvas object using the auxiliary bitmap we had created before.
canvas = new Canvas(auxBitmap);
Now its time to create our view.
We can add Images, for example:
ImageView newImage = new ImageView(mContext);
newImage.setImageBitmap(bitmapWithImage)
We can set the imageView position in the view using “layout” method:
newImage.layout(l,t,r,b);
l Left position, relative to parent
t Top position, relative to parent
r Right position, relative to parent
b Bottom position, relative to parent
and finally adding it to our layout:
relativeView.addView(newImage);
or we can add text:
TextView newText = new TextView(mContext);
newText.setText(“This is the text that its going to appear”);
adding it to the layout in the same way:
relativeView.addView(newText);
Once we have added all elements we want to our layout, we have to create a paint object:
Paint paint = new Paint();
just to define default values of painting.
We use the “drawBitmap” method from the canvas:
canvas.drawBitmap(ViewBgrnd, 0, 0, paint);
and finally we call dispatchDraw in the layout to draw the children views (imageView, textView) in the canvas.
relativeView.dispatchDraw(canvas);
The returnedBitmap is the bitmap that contains the drawing of the views in the canvas, on it, we have the layout and its childrens as a Bitmap, after painting them in the Canvas.
Conclusion
This is really tricky and maybe difficult to understand. It took me time to understand how it worked. I will try to summarize it:
We need to create a empty bitmap. This bitmap will be the final bitmap with the views on it.
We create the canvas using that bitmap.
We create a layout and we add as many elements as we want.
We attach the layout to the canvas.
Because we have created the canvas using a bitmap object, all that is drawn in the canvas, will be drawn in the bitmap.
From: Bright hub
This code was supposed to convert text to image
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setTextSize(16);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.MONOSPACE);
Bitmap bm = Bitmap.createBitmap(16, 16, Bitmap.Config.ALPHA_8);
float x = bm.getWidth();
float y = bm.getHeight();
Canvas c = new Canvas(bm);
c.drawText("Test", x, y, paint);
}
Is this code ok? If yes, how can I make this new bitmap visible on screen? I tried this code which produced an error
setContentView(c); //<- ERROR!
I am confused with the element Canvas as there is not such element in XML which I can use in the code.
setContentView(View) takes a View and Canvas is not a View.
I am not sure that you want to create a Canvas on your own. There are ways to get a Canvas passed to you from the Android Framework though. One way you can do this is by creating a custom View. To do this, you will need to create a new class that extends View.
When overriding a View class, you will have the ability to override the onDraw(Canvas) method. This is probably where you want to do what you are attempting to do in your onCreate() method in the code you posted.
This link gives a good overview of what is required to create your own custom view.
First: If you draw your text at the x and y position you specified, you draw it
at the lower right corner, starting with exactly that pixel. Nothing will be drawn on your canvas. Try bm.getWidth()/2, for height the same for test drawing. You can optimize that later.
Second: Canvas is not a View (does not extend the View class). You can only set Views via set ContentView(). What I recommend here is writing a XML layout containing only a single ImageView and set that via setContentView(R.layout.mylayout).
After that, you can use findViewById() to grab that ImageView and use ImageView.setImageBitmap(bm) to show your bitmap on it.
You dont have to do anything with the canvas, once you created it with your bitmap. Everything you draw inside the canvas from that point on is found in the Bitmap immediately.
Therefore you can't specify the Canvas in XML. It's just an "Editor" to edit pictures, so to speak and not an actual UI element.
i have a seekbar which i implemented in an xml file. i wanted to place this seekbar on a custom drawable rectangle which i have drawn using the canvas draw method and i have named the the class as "controlButtons.java", i.e different rectangles will act as menus as if.
my main problem is how should i make the seekbar appear on the rectangle without having to make the class "extend linearlayout".
is there a way to import something as a linearlayout and place it on the canvas
hope you'll be able to help me..thanks
raaj
Hope this help:
Bitmap bitmap = Bitmap.createBitmap(seekBarView.getMeasuredWidth(),
seekBarView.getMeasuredHeight() ,Bitmap.Config.ARGB_8888);
Canvas barCanvas = new Canvas(bitmap);
seekBarView.draw(canvas);
baseCanvas.drawBitmap(bitmap, x, y, null);
What I would do is create a bitmap from the canvas that contains the "custom drawable rectangle" using canvas.setBitmap(bitmap);. Then I would use TableLayout in XML to place the bitmap (using imageView) behind the seekbar. The gives you the ability to control the seekbar and get data from it without having to redraw the canvas again completly.