Draw using canvas on Home screen widget - android

My Desired Output:
Text on the widget(Home Screen Widget) with custom font
My Problems:
Can not use custom font on textview in widget (As TextView's are not directly accessable in widgets, we have to use them using remoteviews.)
So i thought to use imageview and draw text on bitmap using canvas and then set this bitmap on the imageview. So far everything is working but just two thing.
I dont know,
how to make my text to set vertically and horizontally on centre? (Vertically and horizontally means, to be in centre both vertically and horizontally)
how to make my text to fill the entire space of bitmap?
I am using following code to show some text on the widget.
Bitmap bitmap = Bitmap.createBitmap(200, 200, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
canvas.drawPaint(paint);
paint.setColor(Color.GREEN);
paint.setStyle(Style.FILL);
canvas.drawText("Test", 50, 50, paint);
and following is the output.

1- Setting font runtime on textview in widget
I dont know that either
2- Setting text to be in center and fill the container
Please see the following code:
float size = 1.0f;
Bitmap bitmap = Bitmap.createBitmap(200, 200, Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
paint.setColor(Color.YELLOW);
canvas.drawPaint(paint);
paint.setColor(Color.GREEN);
paint.setStyle(Style.FILL);
Rect rect = new Rect();
paint.getTextBounds("Test", 0, 4, rect);
float width = 1.0f;
while (width<200 && rect.height()<200)
{
size++;
paint.setTextSize(size);
width = paint.measureText("Test");
paint.getTextBounds("Test", 0, 4, rect);
}
size--;
paint.setTextSize(size);
canvas.drawText("Test", 100-width/2, 100+rect.height()/2, paint);
I was trying to attach the screen shot but it wont allow me to add as i am a new user.(rookie :P)
Thanks,

Hello Why you can't use a custom font on TextView: i think you can just subclass TextView and add this the three default text view constructor
if (!isInEditMode()) {
Typeface tf = Typeface.createFromAsset(getContext().getAssets(), "fonts/ds_digib.ttf");
setTypeface(tf);
}
To make your text set vertically and horizontally
see this link
hope this will help you to resolve your problem

Can not use custom font on textview in widget
TextView tv=(TextView)findViewById(R.id.custom);
Typeface face=Typeface.createFromAsset(getAssets(),"fonts/Verdana.ttf");
tv.setTypeface(face);
if you want to use same in canvas then set the face to paint obj which u r using.
how to make my text to set vertically and horizontally on centre?
In canvas as your drawing text by paint obj. then you can set paint obj
mPaint.setTextAlign(Align.CENTER);
or you can place to left or right. You can't set vertically or horizontally because ur drawing the text so you draw as you want vertically or horizontally.
example you need to draw text SAM
horizontally means canvas.drawText("SAM", 50, 50, paint);
veritically means
canvas.drawText("S", 50, 50, paint);
canvas.drawText("A", 50, 51, paint);
canvas.drawText("M", 50, 52, paint);
NOTE : then you might think what is mPaint.setTextAlign(Align.CENTER), right or left. so example if you ve 100 widht and you start writing from 20px to 50px means then its tries to keep in center from 20 to 50 px. NOT in center to widht 100px.
how to make my text to fill the entire space of bitmap?
You will not find any wrap content here because in Canvas we have to our self.
so first check how much space u have and fill the give x and y values and also change the text-size prepositionally .

Related

How can we specify the text size, type, density when creating bitmap

I'm trying to create a bitmap with text on it. but I'm having troubles in specifying the options for that text, like the size, type, smoothness.
Here is my code:
Bitmap resultBitmap=Bitmap.createBitmap(384,384, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
paint.setColor(Color.BLACK); // Text Color
paint.setStrokeWidth(24); // Text Size
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); // Text Overlapping Pattern
// some more settings...
canvas.drawBitmap(resultBitmap, 0, 0, paint);
canvas.drawText("00: Some text", 300, 10, paint);
These options are available in the paint that will be used to draw the text on the canvas. Check for yourself with the autocomplete on android studio. Note that the color will be the paints original color, so there's no setTextColor method available.
The problem with density was the size of the bitmap itself, while it's small, the printed texts cannot be smooth!
Text size:
paint.setTextSize(fontSize);
density is the same problem like smoothing, so just make it bigger.
type:
paint.setTypeface(Typeface.create(Typeface.DEFAULT_BOLD, Typeface.BOLD));
color:
paint.setColor(Color.BLACK);
background color:
canvas.drawColor(Color.WHITE);

in android trying to create an image by taking the width and height of textview

I have created my layout and textview dynamically and set the textview width to certain value and the hieght as fill_parent.
While doing
tv = new TextView(this);
tv.setLayoutParams(new LayoutParams(500, LayoutParams.WRAP_CONTENT));
tv.setText("Hello world how are you whats up whats up hows life is good oh great");
tv.setTextColor(Color.BLACK);
tv.setBackgroundColor(Color.TRANSPARENT);
tv.setTextSize(24);
ll.addView(tv);
this.setContentView(ll);
its showing the content nicely and wrapping it correctly
Hello world how are you whats up
whats up hows life is good
oh great
but when i try to extract this textview width and height and try to create an image of same width and same height, its generating a smaller width image by cutting the Correctly word y partially.
bitmap = Bitmap.createBitmap(tv.getWidth(),tv.getHeight(),Config.RGB_565);
canvas=new Canvas(bitmap);
canvas.drawARGB(255,0,255,0);
paint.setStyle(Style.FILL);
paint.setColor(Color.BLUE);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.SERIF);
paint.setTextSize((int) 24);
canvas.drawText(tv.getText().toString().substring(0,44),0,27, paint);
canvas.drawText(tv.getText().toString().substring(tv.getLayout().getLineStart(1),tv.getLayout().getLineStart(2)),0,48, paint);
canvas.drawText(tv.getText().toString().substring(tv.getLayout().getLineStart(2),tv.getLayout().getLineStart(3)),0,48+24, paint);
canvas.save();
Whats the problem.
I tried this too
bitmap = Bitmap.createBitmap(tv.getWidth(),tv.getHeight(),Config.RGB_565);
canvas=new Canvas(bitmap);
canvas.drawARGB(255,0,255,0);
final TextPaint paint = new TextPaint(Color.BLUE);
paint.setStyle(Style.FILL);
paint.setAntiAlias(true);
paint.setTypeface(Typeface.SERIF);
paint.setTextSize((int) 24);
canvas.save();
StaticLayout sl= new StaticLayout(tv.getText().toString(), paint, bitmap.getWidth(), android.text.Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
sl.draw(canvas);
But in the result i am getting a line cutting the text and an underline too. Please Advice
TextViews word wrap. DrawText does not, by design. If you need that, you need to use StaticLayout to do the wrapping.

Draw a border (Paint) on current clip (created by different Region.Op)

I want to draw an image into shape of a Path and then add border on the Path. I was able to clip the image with Path but can't find a way to add border on it. I though it would be simple because the API supports Paint object on Canvas.draw* methods.
I asked another question at: Draw bitmap on current clip in canvas with border (Paint) and I accepted the answer. However, after that I found that I need to do a little bit more complicated processing. Because I use two options for clipping instead of one.
Below is my code to clip and image with two different Region.Op parameters
Bitmap srcImage = BitmapFactory.decodeStream(getAssets().open("panda.jpg"));
Bitmap bitmapResult = Bitmap.createBitmap(srcImage.getWidth(), srcImage.getHeight(), Bitmap.Config.ARGB_8888);
Path path = new Path();
// This is my border
Paint paint = new Paint();
paint.setStyle(Style.STROKE);
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
paint.setAntiAlias(true);
Canvas canvas = new Canvas(bitmapResult);
// Overlay two rectangles
path.addRect(10, 10, 70, 70, Path.Direction.CCW);
path.addRect(40, 40, 120, 120, Path.Direction.CCW);
canvas.drawPath(path , paint);
canvas.clipPath(path, Region.Op.INTERSECT);
// Draw the circle
path.reset();
path.addCircle(40, 80, 20, Path.Direction.CCW);
canvas.drawPath(path , paint);
canvas.clipPath(path, Region.Op.DIFFERENCE);
// The image is drawn within the area of two rectangles and a circle
// Although I suppose that puting Paint object into drawBitmap() method will add a red border on result image but it doesn't work
canvas.drawBitmap(srcImage, 0, 0, paint);
((ImageView)this.findViewById(R.id.imageView1)).setImageBitmap(bitmapResult);
Here is the result from my code: http://i.stack.imgur.com/8j2Kg.png
And this is what I expect: http://i.stack.imgur.com/iKhIr.png
Do I miss anything to make it work ?

Autofit text in a rectangle on android

I'm using a view and drawing over a bitmap some text,it does not have a fixed size, so I want the text to fit the rectangle I define and if it's needed split the string in some lines.
I don't know how to do it in android.
I found one solution using StaticLayout, but doesn't work.
Here is my code:
Bitmap arBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ar_bitmap);
canvas.drawBitmap(arBitmap ,bitmapPos,20, null);ll);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
canvas.drawText(textToDisplay,textPos , 35, paint);
Thanks

Fill canvas outside rectangle

I want to fill the area outside a rectangle on a canvas. I use
canvas.drawRect(pTopLeft.x, pTopLeft.y, pBotRight.x, pBotRight.y, paint);
to draw the rectangle, but can't figure out how to fill outside the rectangle/clip.
Thanks
Geoff
Thanks ted and trojanfoe - the neatest solution I've come up with is
Point pTopLeft = new Point();
Point pBotRight = new Point();
//TODO:set x,y for points
Rect rHole = new Rect(pTopLeft.x, pTopLeft.y, pBotRight.x, pBotRight.y);
//assume current clip is full canvas
//put a hole in the current clip
canvas.clipRect(rHole, Region.Op.DIFFERENCE);
//fill with semi-transparent red
canvas.drawARGB(50, 255, 0, 0);
//restore full canvas clip for any subsequent operations
canvas.clipRect(new Rect(0, 0, canvas.getWidth(), canvas.getHeight())
, Region.Op.REPLACE);
You aren't going to fill outside the clip; that's the kind of thing clip is there to prevent! If you want to fill the space outside a rect and inside the drawing layer bounds, construct four auxiliary rects:
Rect above = new Rect(0, 0, canvas.getWidth(), pTopLeft.y);
Rect left = new Rect(0, pTopLeft.y, pTopLeft.x, pBotRight.y);
Rect right = new Rect(pBotRight.x, pTopLeft.y, canvas.getWidth(), pBotRight.y);
Rect bottom = new Rect(0, pBotRight.y, canvas.getWidth(), canvas.getHeight());
Then fill these.
ICS and above ...
canvas.clipRect(rHole, Region.Op.DIFFERENCE);
XOR, Difference and ReverseDifference clip modes are
ignored by ICS if hardware acceleration is enabled.
Just disable 2D hardware acceleration in your view:
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Reference Android: Howto use clipRect in API15
You can't draw outside of the Canvas; that area belongs to the parent View. Do you have the ability to subclass the parent View and do your drawing in that class instead?
If you want to draw outside of the Canvas clip then you'll have to invalidate() the areas you are interested in.

Categories

Resources