Android custom View dimensions and canvas coordinates - android

I have custom View that should paint a bitmap. I've created a simple line(bmp 1x50 px) to check where will be drawn exactly. In my onDraw(Canvas c) I'm using this line of code:
canvas.drawBitmap(bitmap, 0, 0, paint);
Where paint is simple Paint object, without any fancy settings. The problem is that this line shows at the middle of the view, not on top, as I thought it would be.
I'm setting View properties in layout xml:
<com.example.CustomView
android:id="#+id/costom_view"
android:layout_width="230px"
android:layout_height="188px"
android:layout_marginTop="10px"
custom:srcDraw="#drawable/menu_indicators_level_draw_up" />
This custom property is the ID of the bitmap I use to draw on canvas.
Why won't the View behave properly? And why does my canvas have a size if 800x450 (size of the screen i suppose) and not 230x188 like I defined in the layout?
And very important thing, I want to multiply the same bitmap on this view many times. At the end of work I want to draw this line from bottom to top of my View.

i think what you should use to draw the line above the bitmap is the follwing :
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)
and give it the right coordinates to be drawn on top of the bitmap .
Hope that helps .

Related

Rounded Rectangle with Android Canvas

I'm attempting to draw a rectangle around a custom view in Android. I mostly have it working except for one detail.
Here is my code...
Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setStrokeWidth(14.5f);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRoundRect(0, 0, getWidth(), getHeight(), 20.0f, 20.0f, paint);
And here is the resulting rectangle...
As you can see, the inside of the rectangle does have rounded corners, but the outside still draws pointed corners. How can I make it so that the outside corners are rounded as well?
You don't see corners rounded on the outside because part of the stroke is outside of the bounds of the Canvas. You can check this easily by adding a certain margin to the coordinates of the round rectangle to make sure it is drawn inside the Canvas.
In fact your best option is trying to optimize this margin depending on the selected stroke width.

Drawing a custom shape

I need to draw a custom shape like the following.
I am trying to draw this on a Canvas for a custom view that i am trying to make. The custom view will represent a fuel level indicator.
Any ideas as to how i can achieve this drawing?
Draw what you are asking using Path, using moveTo(float x, float y) ,lineTo (float x, float y) and close() methods.
The clip the canvas to that path ( using clipPath (Path path) method of the Canvas ).
Then to make some of it red, just draw a red rectangle of appropriate height and length.

How to gradually increase the width of a Canvas?

I'm trying to implement a Waveform visualizer in my app which draws the waveform on a canvas from a real-time audio input. (Screenshot below)
What I need to do is to make it in a way that it can be scrolled horizontally from left to right.
I figured I should use a HorizontalScrollView and make the canvas gradually grow in width so that it spans over the screen width. Now I'm wondering how this can be achieved?
Keep the Canvas's width the same and use the canvas.translate() method when actually drawing.
So, let's say you have a Rect rect that contains the rectangle to draw (whose boundaries may exceed that of the View), as well as int horizontalOffset = 0 as the variable holding the offset of your drawing rectangle which will be adjusted as the user touches the View.
Now, when onDraw(Canvas) is called:
#Override
public void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.save();
canvas.translate(horizontalOffset, 0);
canvas.drawRect(rect, paint);
canvas.restore();
}
Then you can then override onTouch(View, MotionEvent) to calculate the horizontal offset based on the touch event and then invalidate() the View.
Note: this is clearly only drawing a Rect, but you should be able to modify what I did in there to draw whatever you're drawing. The important parts are (in order) save(), translate(), draw, restore().

How to draw a bar diagram on Android

I need to draw a bar diagram like the picture showing below. I am able to draw a ordinary bar diagram with filling a color on text view or some layouts. But this is a bit different.
How do I draw a bar diagram with slanting bars?
.
Try Android canvas and custom View. You can use View's onDraw method. The method provides the canvas. You should try drawArc, drawLine, etc. If your bar view contains a textView, you must use a custom viewgroup.
Do something like this in your onDraw of View.
RectF oval = new RectF();
Paint paint = new Paint();
paint.setColor(ContextCompat.getColor(context, R.color.color1));
paint.setStrokeWidth(widthOfArc);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
canvas.drawPath(path, yourPaint);
oval.set(x1,y1,x2,y2);
//eg:- startAngle = 10, sweepAngle = 40
canvas.drawArc(oval, startAngle, sweepAngle, false, paint);
Please read about how RectF works.
I will update the answer if I found any related blog/tutorial
Calculating start and end angle is pure Mathematics
refer this
http://www.html5canvastutorials.com/tutorials/html5-canvas-arcs/
You have to change the color and keep drawing Arc to get the result.

How to force the canvas to use only a portion of the area to draw text when extending a TextView

I am creating a custom view that extends the TextView. What I need is a couple of labels on the left handside and another checker on the right hand side of the TextView.
So I can draw those labels and then save the canvas and translate it right so that the text can be drawn beside the bitmaps. This is how I am doing that.
canvas.drawBitmap(bitmap1, 0, top, paint);
canvas.drawBitmap(bitmap2, bitmap1_width, top, paint);
canvas.save();
canvas.translate(bitmap1_width + bitmap2_width, 0);
Here I want to call super.onDraw but ask it to use the width so that the widths of the two bitmaps and the checker are subtracted.
Then I am can call my
canvas.drawBitmap(checker, checkerLeft, top, null);
So after translating the canvas, how can I can tell the canvas in the super.onDraw to use only the measured width? Please feel free to throw in any alternatives. I do want to use canvas though since my requirement is a little more complicated than this example.
Ok I did it by changing the scale factor using canvas.scale(sx, sy) before calling super.onDraw().
This is displaying the text in the way I want. If there is a better answer, please post it.
canvas.save();
canvas.translate(margin, 0);
canvas.scale(scaleX, 1f);
super.onDraw(canvas);
canvas.restore();

Categories

Resources