Creating font and text styles in android with Paint object - java

I am using the android Paint class to create text. I know how to set text size and color. I want to use Arial as font size and bold. How can I do it using the paint object. I have looked on the methods in the Paint class but couldn't find anything on how I can do it.
This is how I create my text style.
// Defining a paint object
paint = new Paint();
paint.setTextSize(30);
paint.setTextAlign(Paint.Align.LEFT);
paint.setAntiAlias(true);
paint.setColor(Color.WHITE);
Here is how I draw the text on a view.
g.drawString("My Text", 430, 774, paint);
How do I create the Arial font and bold text using the Paint class.

Use the TextPaint class instead of Paint. And can be implemented as below
TextPaint textPaint = new TextPaint();
textPaint.setTextSize(30);
textPaint.setTextAlign(Paint.Align.LEFT);
textPaint.setColor(Color.WHITE);
textPaint.setTypeface(Typeface.create("Arial", Typeface.BOLD));

Januari 2020
Copy the fonts you want to use to res/font
(e.g. opensans_regular.ttf, opensans_italic.ttf, opensans_bolditalic.ttf, etc.)
Watch out no '-' of capitals in the name!
Create New Font resource file opensans.xml
<?xml version="1.0" encoding="utf-8"?>
<font-family
xmlns:app="http://schemas.android.com/apk/res-auto">
<font
app:fontStyle="normal"
app:fontWeight="400"
app:font="#font/opensans_regular" />
<font
app:fontStyle="italic"
app:fontWeight="400"
app:font="#font/opensans_italic" />
<font
app:fontStyle="normal"
app:fontWeight="700"
app:font="#font/opensans_bold" />
<font
app:fontStyle="italic"
app:fontWeight="700"
app:font="#font/opensans_bolditalic" />
<font
app:fontStyle="normal"
app:fontWeight="200"
app:font="#font/opensans_light" />
<font
app:fontStyle="italic"
app:fontWeight="200"
app:font="#font/opensans_lightitalic" />
<font
app:fontStyle="normal"
app:fontWeight="800"
app:font="#font/opensans_extrabold" />
<font
app:fontStyle="italic"
app:fontWeight="800"
app:font="#font/opensans_extrabolditalic" />
</font-family>
In your MainActivity.java you can use the following code
Paint paint = new Paint();
Typeface typeface;
if (Build.VERSION.SDK_INT >= 28) {
// This does only works from SDK 28 and higher
Typeface typefaceA = ResourcesCompat.getFont(this, R.font.opensans);
typeface = Typeface.create(typefaceA, 700, false);
} else {
// This always works (Whole name without .ttf)
typeface = ResourcesCompat.getFont(this, R.font.opensans_bolditalic);
}
paint.setTypeface(typeface);

private Bitmap getFontBitmap(String text, int color, float fontSizeSP, int typefaceStyle, boolean isCustomFont) {
Paint paint = new Paint();
paint.setAntiAlias(true);
if (isCustomFont) {
Typeface typeface = Typeface.create(Typeface.createFromAsset(mContext.getAssets(), "fonts/bangla/bensen_handwriting.ttf"), typefaceStyle);
paint.setTypeface(typeface);
} else {
Typeface typeface = Typeface.create(Typeface.DEFAULT, typefaceStyle);
paint.setTypeface(typeface);
}
int fontSizePX = ConvertDptoPx(mContext, fontSizeSP);
int pad = (fontSizePX / 9);
paint.setColor(color);
paint.setTextSize(fontSizePX);
int textWidth = (int) (paint.measureText(text) + pad * 2);
int height = (int) (fontSizePX / 0.75);
Bitmap bitmap = Bitmap.createBitmap(textWidth, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
float xOriginal = pad;
canvas.drawText(text, xOriginal, fontSizePX, paint);
return bitmap;
}
private int ConvertDptoPx(Context context, float dip) {
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, context.getResources().getDisplayMetrics());
}
And then call
Bitmap bitmap = getFontBitmap("Ahamadullah", color, 22, Typeface.BOLD, true);
or
Bitmap bitmap = getFontBitmap("Ahamadullah", color, 22, Typeface.NORMAL | Typeface.ITALIC, false);

Related

how to set Custom font for Widget?

i want to set custom font for TextView in widget,How?
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.weather_widget);
views.setTextViewText(R.id.txv_widget_location, "my text");
Just replace xyz.ttf with your chosen font.
public Bitmap createBitmap(String texttoshow)
{
Bitmap myBitmap = Bitmap.createBitmap(160, 84, Bitmap.Config.ARGB_8888);
Canvas myCanvas = new Canvas(myBitmap);
Paint paint = new Paint();
Typeface weatherwidget = Typeface.createFromAsset(this.getAssets(),"xyz.ttf");
paint.setAntiAlias(true);
paint.setSubpixelText(true);
paint.setTypeface(weatherwidget);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTextSize(65);
paint.setTextAlign(Align.CENTER);
myCanvas.drawText(texttoshow, 80, 60, paint);
return myBitmap;
}
The above code applies the font and text to image view.
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.weather_widget);
views.setImageViewBitmap(R.id.txv_widget_location, createBitmap("my_text"));

Custom shaped layout with bottom line curved in Android

I want to make a layout like the one in the picture with the bottom curved.
I tried doing using some examples in stackoverflow but cannot get the exact idea how to do this.
Right now i was trying to do using a drawable xml and including that in the layout:
`<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners
android:bottomLeftRadius="0dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
<padding
android:bottom="5dp"
android:left="20dp"
android:right="0dp"
android:top="0dp" />
<stroke
android:width="0.5dp"
android:color="#color/colorPrimary" />
<solid android:color="#color/colorPrimary" />
</shape>`
You can do it as -
create as Custom View as -
public class CustomDrawableView extends View {
Paint paint;
void init(){
paint = new Paint();
}
}
Now in onDraw() Method you can draw as -
first draw a rectangle having height = getHeight()/2
width = getWidth()
onDraw(Canvas canvas){
Rect r = new Rect(0, 0, width , height );
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
canvas.drawRect(r, paint);
int centerX=widht;
int centerY = -50;
int radius = Math.sqrt((0-centerX)*(0-centerX) + (height-centerY )*(height-centerY));
canvas.drawCircle(width, height -50 , radius, paint); // for big circle
}
Set height and width of CustomDrawableView to match parent and you can also adjust center as you want.

Animate rotation of an image in Android

I have a gear image which I want to continuously rotate about a fixed point.
Earlier I was accomplishing this by including the image in my Android class as an ImageView and applying a RotateAnimation to it.
#InjectView(R.id.gear00) ImageView gear00;
RotateAnimation ra07 = new RotateAnimation(0, 359, 129, 186);
ra07.setDuration(10000);
ra07.setRepeatCount(RotateAnimation.INFINITE);
ra07.setInterpolator(new LinearInterpolator());
gear00.setAnimation(ra07);
Basically, I was injecting the ImageView into the class and applying a rotation animation.
However, I dont have the luxury of using an ImageView anymore. I have to use a Bitmap and rotate it on the canvas.
How can I go about accomplishing what I was doing earlier in the onDraw() method with a bitmap rotating about a fixed point continiously on the canvas?
Edit1:
I tried one of the suggestions mentioned below my code looks a little like the following
in onCreate():
Matrix matrix = new Matrix();
matrix.setRotate(10, 100, 200);
Then in onDraw() (where gear00Scaled is a bitmap to be rotated on the canvas):
canvas.drawBitmap(gear00Scaled, matrix, new Paint());
Another method I tried involved saving the canvas, rotating it, then restoring it:
canvas.save();
canvas.rotate(10);
canvas.drawBitmap(gear00Scaled, 100, 200, null);
canvas.restore();
Neither seem to be working though!
Make an XML class (suppose: rotate.xml) and place it in res/anim folder and then write the following code in it:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:interpolator="#android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="360" />
Then in your java class, do the following in OnCreate:
final Animation a = AnimationUtils.loadAnimation(CustomActivity.this,
R.anim.rotate);
a.setDuration(3000);
gear00.startAnimation(a);
OR
To do it using bitmap, I hope the following sequence of code helps you:
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight, config);
Canvas canvas = new Canvas(targetBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
canvas.drawBitmap(source, matrix, new Paint());
If you check the following method from:
~frameworks\base\graphics\java\android\graphics\Bitmap.java
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
Matrix m, boolean filter)
this would explain what it does with rotation and translate.
I want to rotate a custom image as progress dialog in my application. You can use the code below to rotate an image:
RotateAnimation anim = new RotateAnimation(0.0f, 360.0f ,
Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(1000);
imageView.setAnimation(anim);
imageView.startAnimation(anim);
In your onCreate() do
Matrix matrix = new Matrix();
And in onDraw
float angle = (float) (System.currentTimeMillis() % ROTATE_TIME_MILLIS)
/ ROTATE_TIME_MILLIS * 360;
matrix.reset();
matrix.postTranslate(-source.getWidth() / 2, -source.getHeight() / 2);
matrix.postRotate(angle);
matrix.postTranslate(centerX, centerY)
canvas.drawBitmap(source, matrix, null);
invalidate(); // Cause a re-draw
ROTATE_TIME_MILLIS is the full circle time, e.g. 2000 is 2 seconds.
Two things before the code:
You can't use imageview at all at all? Cause you could link it to a canvas and use a bitmap, but it is still an imageview.
I believe the main issue you are having is the other answer is not animating it and you are missing the call to invalidate() the view and redraw it as rotated.
So there are two approaches:
1st is with the imageview, personally I think it is easier and nicer. Below is a method in my activity class and mLittleChef is an ImageView.
public void doCanvas(){
//Create our resources
Bitmap bitmap = Bitmap.createBitmap(mLittleChef.getWidth(), mLittleChef.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
final Bitmap chefBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.dish_special);
//Link the canvas to our ImageView
mLittleChef.setImageBitmap(bitmap);
ValueAnimator animation= ValueAnimator.ofFloat(0, 359, 129, 186);
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
//Clear the canvas
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.save();
canvas.rotate(value, canvas.getWidth()/2, canvas.getHeight()/2);
canvas.drawBitmap(chefBitmap, 0, 0, null);
canvas.restore();
mLittleChef.invalidate();
}
});
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(1000);
animation.start();
}
The other way to do it is with a custom canvas class. Instead of an ImageView, I create my own custom view class for ExampleDrawView mLittleChefDraw; in my layout. You will probably have to monkey with this one a bit to get exactly what you are looking for in terms of rotation, I made it just do a 360 degree turn using the middle of the canvas as the pivot point.
public class ExampleDrawView extends View {
Bitmap bitmap;
Float mRotate= 0f;
Handler h;
//State variables
final int STATE_PAUSE = 2;
final int STATE_ROTATE = 3;
int STATE_CURRENT;
public ExampleDrawView(Context context, AttributeSet attrs) {
super(context, attrs);
h = new Handler();
bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.dish_special);
STATE_CURRENT= STATE_PAUSE;
}
Runnable move = new Runnable() {
#Override
public void run() {
switch (STATE_CURRENT){
case STATE_ROTATE:
if (mRotate<360){
mRotate++;
invalidate();
}else{
STATE_CURRENT= STATE_PAUSE;
}
h.postDelayed(move, 20);
break;
}
}
};
public void startDrawing(){
if(STATE_CURRENT == STATE_PAUSE){
STATE_CURRENT= STATE_ROTATE;
mRotate=(float) 0;
h.postDelayed(move, 20);
}
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//change your rotate point here, i just made it the middle of the canvas
canvas.rotate(mRotate,getWidth()/2,getHeight()/2);
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
And then back in the activity call this to start it:
public void doCanvasCustomView(){
mLittleChefDraw.startDrawing();
}

how to scale a rect in android?

I want to be able to scale a Rect on android so it fits the whole screen this is my code so far:
public class MainView extends View {
private Main main;
private Rect facebook_rect;
public MainView(Context context){
super(context);
this.main = (Main) context;
setFocusable(true);
setFocusableInTouchMode(true);
}
#Override
protected void onDraw(Canvas canvas){
Paint background = new Paint();
background.setColor(getResources().getColor(R.color.main_background));
canvas.drawRect(0, 0, getWidth(), getHeight(), background);
Paint facebookPaint = new Paint();
facebook_rect = new Rect(0,0,getWidth(),getHeight()/5);
facebookPaint.setColor(getResources().getColor(R.color.facebook_color));
canvas.drawRect(facebook_rect,facebookPaint);
}
#Override
public boolean onTouchEvent(MotionEvent event){
if(event.getAction()!=MotionEvent.ACTION_DOWN)
return super.onTouchEvent(event);
animate("facebook");
return true;
}
private void animate(String string) {
Animation anim = AnimationUtils.loadAnimation(main, R.anim.scale_anim_1stpos);
facebook_rect.startAnimation(anim);
}
}
however this : "facebook_rect.startAnimation(anim);" does not work... any ideas on how to do this?
edit: I also have this as my anim xml file
<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:fromYScale="1.0" android:toYScale="3.0"
android:pivotX="0"
android:pivotY="0"
android:interpolator="#android:anim/linear_interpolator"
android:duration="700" android:fillAfter="true" >
</scale>
The effect I'm trying to achieve is something like passbook Apple's new ticket app just in case you have a better idea how to do it. thanks!
If you want to scale something you can use canvas.scale(scaleFactor, scaleFactor);
The first scale factor is the amount you want to scale in X, and the second the amount in Y.
For the animation part take a look at this link, maybe it can help.
First take the sceeen dimensions
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics );
Next find the scale factor
float scale = displayMetrics.densityDpi;
Next scale the canvas using draw function
canvas.drawRect(left-20*scale, top-20*scale, right+20*scale, bottom, mPaint);

Android Custom Brush Colors

I'm trying to make custom brushes for my Android painting app. I started with Michael's code (found here) and I have managed to get .png brushes and use that as a bitmap and redraw it. It works fine but I can't change the colour. Tried using the setcolorfilter and colormatrixfilter but it doesn't seem to be working. Anyone knows how I can do this?
private Bitmap mBitmapBrush;
private Vector2 mBitmapBrushDimensions;
private List<Vector2> mPositions = new ArrayList<Vector2>(100);
private Paint mPanit;
public MyView(Context c) {
super(c);
mPath = new Path();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
mBitmapBrush = BitmapFactory.decodeResource(c.getResources(),R.drawable.brush1);
mBitmapBrushDimensions = new Vector2(mBitmapBrush.getWidth(), mBitmapBrush.getHeight());
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(0xFFAAAAAA);
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
for (Vector2 pos : mPositions) {
canvas.drawBitmap(mBitmapBrush, pos.a, pos.b, mPanit);
}
invalidate();
}
When I tried using the Colormatrixfilter, the .set function was giving an error.
I had the same issue. In order to change the bitmap color you need to add color to your paint object and apply it into bitmap. See the working example here,
for (Vector2 pos : customBrushMap.get(p)) {
Paint paint = new Paint();
ColorFilter filter = new PorterDuffColorFilter(R.Color.GREEN, PorterDuff.Mode.SRC_IN);
paint.setColorFilter(filter);
canvas.drawBitmap(mBitmapBrush, pos.x, pos.y, paint);
}
Result,

Categories