I want to set a custom font in my app and done that by
Is it possible to set a custom font for entire of application?
and i have done it but the problem is when i apply AppTheme_1 it changes font for android version greater than or equal to lollipop and when i apply AppTheme_2
then it changes fonts for only android version less than lollipop. But I want to change the font for all android versions.
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
</style>
<style name="AppTheme_1" parent="AppBaseTheme">
<!-- Customize your theme here. -->
<item name="android:textAppearance">#style/CustomTextAppearance</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">#null</item>
</style>
<style name="CustomTextAppearance">
<item name="android:typeface">serif</item>
</style>
</style>
<style name="AppTheme_2" parent="AppBaseTheme">
<!-- Customize your theme here. -->
<item name="android:typeface">serif</item>
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFullscreen">true</item>
<item name="windowNoTitle">true</item>
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">#null</item>
</style>
We can achieve to set a single font to entire application using Calligraphy lib
Here is the library link: Calligraphy
Now add compile 'uk.co.chrisjenx:calligraphy:2.3.0' in your build.gradle
Now create an application class like follows:
public class MyApplication extends Application {
private static MyApplication sInstance;
public static MyApplication getInstance() {
return sInstance;
}
#Override
public void onCreate() {
super.onCreate();
sInstance = this;
CalligraphyConfig.initDefault(new CalligraphyConfig.Builder()
.setDefaultFontPath("fonts/Roboto-Regular.ttf")
.setFontAttrId(R.attr.fontPath)
.build());
}}
Now you need to call this application class in manifest file like follows in application tag
android:name=".MyApplication"
By doing this entire app have set one font. You can go through the library for better understanding.
Try this
MyApplication.java (This is Application class)
//Typeface
public static Typeface poppinsSemiBold;
public static Typeface helveticaNeueMedium;
public static Typeface poppinsRegular;
/**
* Preload typefaces.
*/
private void preloadTypefaces() {
poppinsSemiBold = Typefaces.get(getApplicationContext(), Typefaces.FONT_POPPINS_SEMI_BOLD);
helveticaNeueMedium = Typefaces.get(getApplicationContext(), Typefaces.FONT_HELVETICANEUE_MEDIUM);
poppinsRegular = Typefaces.get(getApplicationContext(), Typefaces.FONT_POPPINS_REGULAR);
}
call this preloadTypefaces() in onCreate() of same class MyApplication.java
Typefaces.java
import android.content.Context;
import android.graphics.Typeface;
import android.util.Log;
import java.util.Hashtable;
public class Typefaces {
private static final String TAG = Typefaces.class.getSimpleName();
public static final String FONT_POPPINS_SEMI_BOLD = "fonts/Poppins_SemiBold.ttf";
public static final String FONT_HELVETICANEUE_MEDIUM = "fonts/HelveticaNeue_Medium.otf";
public static final String FONT_POPPINS_REGULAR = "fonts/Poppins_Regular.ttf";
private static final Hashtable<String, Typeface> cache = new Hashtable<String, Typeface>();
public static Typeface get(Context c, String assetPath) {
synchronized (cache) {
if (!cache.containsKey(assetPath)) {
try {
Typeface t = Typeface.createFromAsset(c.getAssets(), assetPath);
cache.put(assetPath, t);
} catch (Exception e) {
Log.e(TAG, "Could not get typeface '" + assetPath
+ "' because " + e.getMessage());
return null;
}
}
return cache.get(assetPath);
}
}
}
Make sure your .ttf or .otf file is in assets/fonts/HelveticaNeue_Medium.otf added like that
res/values/attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomFontTextView">
<attr name="fontStyle" format="enum">
<enum name="poppinsSemiBold" value="1" />
<enum name="helveticaNeueMedium" value="2" />
<enum name="poppinsRegular" value="3" />
</attr>
</declare-styleable>
<declare-styleable name="TextViewPlus">
<attr name="customFont" format="string" />
</declare-styleable>
</resources>
Custom Font class
TextViewPlus.java
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.TextView;
import com.offerbuk.R;
import com.offerbuk.app.MyApplication;
public class TextViewPlus extends TextView {
private static final String TAG = "TextViewPlus";
private int fontStyle;
private TypedArray a = null;
public TextViewPlus(Context context) {
super(context);
init(null, 0);
}
public TextViewPlus(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs, 0);
}
public TextViewPlus(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs, defStyle);
}
private void init(AttributeSet attrs, int defStyle) {
try {
this.a = getContext().obtainStyledAttributes(attrs, R.styleable.CustomFontTextView, defStyle, 0);
this.fontStyle = a.getInteger(R.styleable.CustomFontTextView_fontStyle, 0);
} finally {
if (this.a != null)
this.a.recycle();
}
if (!isInEditMode()) {
switch (fontStyle) {
case 1:
setTypeface(MyApplication.poppinsSemiBold);
break;
case 2:
setTypeface(MyApplication.helveticaNeueMedium);
break;
case 3:
setTypeface(MyApplication.poppinsRegular);
break;
default:
setTypeface(MyApplication.poppinsRegular);
break;
}
}
}
}
Use this in Your layout file
<TextViewPlus
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:fontStyle="poppinsRegular" />
Related
First of all I am pretty new in programming Xamarin and Android. I have created a SeekbarPreference but some how they layout does not display all correctly. The value is dropping of from the box (see picture).
My styles.xml:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="MyTheme" parent="MyTheme.Base">
</style>
<style name="MyTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#EC6A1E</item>
<item name="colorAccent">#EC6A1E</item>
<item name="toolbarStyle">#style/custom_toolbar</item>
<item name="preferenceTheme">#style/PreferenceThemeOverlay.v14.Material.Fix</item>
</style>
<style name="custom_toolbar" parent="#style/Widget.AppCompat.Toolbar">
<item name="titleTextColor">#FFFFFF</item>
</style>
<style name="PreferenceThemeOverlay.v14.Material.Fix" parent="PreferenceThemeOverlay.v14.Material">
<item name="seekBarPreferenceStyle">#style/Preference.SeekBarPreference.Fix</item>
</style>
<style name="Preference.SeekBarPreference.Fix">
</style>
</resources>
Here is my settings.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.preference.PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.preference.SeekBarPreference
android:id="#+id/preference_range_seek_bar"
android:layout_height="wrap_content"
android:key="range"
android:title="Range"
android:summary="Here you can set the range of your location"
android:max="10000"
android:defaultValue="500" />
<android.support.v7.preference.SeekBarPreference
android:key="favRange"
android:title="Favorite Range"
android:summary="Here you can set the range of your Favorite location"
android:max="10000"
android:defaultValue="500" />
<android.support.v7.preference.Preference android:title="Title" android:summary="This is the summary">
</android.support.v7.preference.Preference>
</android.support.v7.preference.PreferenceScreen>
What I do not understand is how can I find which xml attributes I can use on the SeekBarPreference to fix this. When I look in Googles Documents I cannot find a description of xml attributes on this SeekBarPreference.
I know my theme is fuzzy as I played a lot with it. But when I have it working I will adjust this.
Hopefully someone could help me, or have an example..
Ran into the same issue. Here you go with the solution, testion on emulator running API 25:
Step 1, Create a new class that extends SeekBarPreference
public class CustomSeekBarPreference extends SeekBarPreference {
private TextView mSeekBarValueTextView;
public CustomSeekBarPreference(Context context,
AttributeSet attributeSet,
int i, int i1) {
super(context, attributeSet, i, i1);
}
public CustomSeekBarPreference(Context context, AttributeSet attributeSet, int i) {
super(context, attributeSet, i);
}
public CustomSeekBarPreference(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
public CustomSeekBarPreference(Context context) {
super(context);
}
#Override
public void onBindViewHolder(PreferenceViewHolder preferenceViewHolder) {
super.onBindViewHolder(preferenceViewHolder);
mSeekBarValueTextView = (TextView) preferenceViewHolder.findViewById(android.support.v7.preference.R.id.seekbar_value);
if (mSeekBarValueTextView != null) {
LayoutParams layoutParams = mSeekBarValueTextView.getLayoutParams();
layoutParams.height = LayoutParams.WRAP_CONTENT;
mSeekBarValueTextView.setLayoutParams(layoutParams);
}
}
}
In your preferences.xml replace the SeekBarPreference class name with the custom class name.
<com.google.xxx.view.CustomSeekBarPreference
android:key="cacheLimit"
android:title="#string/setting_cache_limit_title"
android:dependency="enableCaching"
android:defaultValue="20"
android:max="40"/>
I have a custom view which contains several RobotoTextViews and I want to set typefaces for them.
So, I use declare-styleable item like this:
<declare-styleable name="CustomView">
<attr name="firstTextviewStyle" format="reference" />
<attr name="secondTextviewStyle" format="reference" />
</declare-styleable>
The attributes are referenced to styles.
<style name="firstTextAppearance">
<item name="typeface">roboto_medium</item>
<item name="android:textSize">16sp</item>
<item name="android:textColor">#android:color/white</item>
</style>
So, question is, how to get typeface attr value from this?
#nullpex you can do something like this for dynamic or runtime font change in your app like the following example. You can also use it in your layout file cuz there is custom view also with custom attributes.
I have created a repository for the following code on GitHub
https://github.com/harsh159357/customtextview
Feel free to ask any question
CustomTextViewActivity.java
package com.harsh.customtextview;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class CustomTextViewActivity extends AppCompatActivity implements View.OnClickListener {
CustomTextView customTextView1, customTextView2;
Button changeToRoboto, changeToCalculus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text_view);
customTextView1 = (CustomTextView) findViewById(R.id.customTextView1);
customTextView2 = (CustomTextView) findViewById(R.id.customTextView2);
changeToRoboto = (Button) findViewById(R.id.change_to_roboto);
changeToCalculus = (Button) findViewById(R.id.change_to_calculus);
changeToRoboto.setOnClickListener(this);
changeToCalculus.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.change_to_roboto:
customTextView1.setFont(getString(R.string.font_roboto_regular));
customTextView2.setFont(getString(R.string.font_roboto_regular));
break;
case R.id.change_to_calculus:
customTextView1.setFont(getString(R.string.font_calculus_sans));
customTextView2.setFont(getString(R.string.font_calculus_sans));
break;
}
}
}
activity_text_view.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:gravity="center"
android:orientation="vertical"
tools:context="com.harsh.customtextview.CustomTextViewActivity">
<com.harsh.customtextview.CustomTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/themed_text"
android:textColor="#color/colorPrimary"
android:textSize="22sp"
app:theme="#style/roboto_theme"/>
<com.harsh.customtextview.CustomTextView
android:id="#+id/customTextView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="#string/calculus_sans"
android:textColor="#color/colorPrimary"
android:textSize="22sp"
app:fonts="#string/font_calculus_sans" />
<com.harsh.customtextview.CustomTextView
android:id="#+id/customTextView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="#string/roboto_regular"
android:textColor="#color/colorPrimary"
android:textSize="24sp"
app:fonts="#string/font_roboto_regular" />
<Button
android:id="#+id/change_to_roboto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Change to Roboto" />
<Button
android:id="#+id/change_to_calculus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Change to Calculus" />
</LinearLayout>
CustomTextView.java
package com.harsh.customtextview;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.TextView;
#SuppressLint("AppCompatCustomView")
public class CustomTextView extends TextView {
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public CustomTextView(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CustomView);
String fontName = a.getString(R.styleable.CustomView_fonts);
try {
if (fontName != null) {
Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontName);
setTypeface(myTypeface);
}
} catch (Exception e) {
e.printStackTrace();
}
a.recycle();
}
}
public void setFont(String fontName) {
setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontName));
}
}
attrs.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="fonts" format="string" />
</declare-styleable>
</resources>
styles.xml
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
</style>
<style name="roboto_theme">
<item name="font">#string/font_calculus_sans</item>
</style>
strings.xml
<resources>
<string name="app_name">CustomTextView</string>
<string name="font_calculus_sans">Calculus_Sans.ttf</string>
<string name="font_roboto_regular">Roboto_Regular.ttf</string>
<string name="calculus_sans">Calculus Sans</string>
<string name="roboto_regular">Roboto Regular</string>
<string name="themed_text">Themed Text</string>
</resources>
In my Android app I have two different themes (light and dark).
For example:
<style name="AppThemeDark" parent="Theme.AppCompat">
<item name="colorPrimary">#android:color/black</item>
<item name="colorPrimaryDark">#android:color/black</item>
<item name="colorAccent">#android:color/holo_red_dark</item>
<item name="android:textColor">#android:color/white</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="AppThemeLight" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="windowActionModeOverlay">true</item>
</style>
So, now I can apply, for example, different text colors to a TextView (white for dark theme and black for light):
<item name="android:textViewStyle">#style/TextViewDark</item>
<style name="TextViewDark">
<item name="android:textColor">?android:attr/colorAccent</item>
</style>
But it will apply to all TextViews.
The main question, is it possible to make in XML (not programmatically) next:
Light theme: Half of TextViews text color black, and another half green.
Black theme: TextViews that black in Light theme - red, and another half - blue (which are green in Light theme).
Create 2 classes extends TextView
public class OneTextView extends TextView {
public OneTextView(Context context) {
super(context);
init(context);
}
public OneTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public OneTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context){
int[] attrs = new int[] { R.attr.myFirstColor};
TypedArray ta = context.obtainStyledAttributes(attrs);
int appColor = ta.getColor(0, 0);
ta.recycle();
// set theme color
setTextColor(appColor);
}
}
public class SecondTextView extends TextView {
public SecondTextView(Context context) {
super(context);
init(context);
}
public SecondTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public SecondTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context){
int[] attrs = new int[] { R.attr.mySecondColor};
TypedArray ta = context.obtainStyledAttributes(attrs);
int appColor = ta.getColor(0, 0);
ta.recycle();
// set theme color
setTextColor(appColor);
}
}
each class you can use in xml like this
<com.route.to.class.OneTextView
android:layout_width="match_parent"
android:layout_height="match_parent" />
OneTextView can have black and red colors
SecondTextView can have green and blue colors
define attr.xml in values
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myFirstColor" format="color" />
<attr name="mySecondColor" format="color" />
</resources>
Then in your styles.xml, define colors for each theme:
<style name="Theme.MyApp" parent="#style/Theme.Light">
<item name="myFirstColor">#color/black</item>
<item name="mySecondColor">#color/green</item>
</style>
<style name="Theme.MyApp.Dark" parent="#style/Theme.Dark">
<item name="myFirstColor">#color/green</item>
<item name="mySecondColor">#color/blue</item>
</style>
you have defined in styles.xml
<style name="TextViewDark">
<item name="android:textColor">?android:attr/colorAccent</item>
</style>
<style name="TextViewLight">
<item name="android:textColor">#color/green</item>
</style>
then you can use it in main.xml
<LinearLayout>
<TextView
android:id="#+id/light_text_view"
android:text"i´m use light theme"
style="#style/TextViewLight"/>
<TextView
android:id="#+id/dark_text_view"
android:text"i´m use darktheme"
style="#style/TextViewDark"/>
</LinearLayout>
you don´t need to define styles in AppThemes
When I changed my minSdkVersion then I am getting this error:
android.view.InflateException: Binary XML file line #43: Error inflating class TextView
Eariler it was working fine before I have made the changes.
Here is my style :
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
<style name="AppTheme.Dark" parent="Theme.AppCompat.NoActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
<item name="colorAccent">#color/white</item>
<item name="colorControlNormal">#color/greyDark</item>
<item name="colorControlActivated">#color/off_white</item>
<item name="android:windowBackground">#color/pink</item>
<item name="android:fontFamily">sans-serif-light</item>
<item name="android:textStyle">normal</item>
<item name="android:windowContentTransitions" tools:targetApi="lollipop">true</item>
<item name="android:windowAllowEnterTransitionOverlap" tools:targetApi="lollipop">true</item>
<item name="android:windowAllowReturnTransitionOverlap" tools:targetApi="lollipop">true</item>
<item name="android:windowSharedElementEnterTransition" tools:targetApi="lollipop">#android:transition/move</item>
<item name="android:windowSharedElementExitTransition" tools:targetApi="lollipop">#android:transition/move</item>
</style>
<style name="AlertDialogCustom" parent="#android:style/Theme.Dialog">
<item name="android:textColor">#color/pink</item>
<item name="android:typeface">normal</item>
<item name="android:height">5dp</item>
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold</item>
<item name="android:background">#color/white</item>
</style>
I guess there is something wrong with the parent property of a style.
If you are changing your version then also change the support library.You have to change the support lib like for e.g.for api 23 you have to chnage the appcompact library version to 23.
Hope this help.:)
You should try changing
<style name="AlertDialogCustom" parent="#android:style/Theme.Dialog">
to
<style name="AlertDialogCustom" parent="Theme.AppCompat.Dialog">
This is the issue with your font family which you are using in style. May be sans-serif-light font is not available in your assests>>fonts folder. So check with this how to use custom fonts in android.
Here are the steps to follow:
Android Studio:
Step1: Adding font family files to app
A) Go to the (project folder)
B) Then app>src>main
C) Create folder 'assets>fonts' into the main folder.
D) Put your 'abc.ttf' or 'abc.otf' font file into the fonts folder.
Step 2:
Now Create attrs.xml under res folder if it's not exists and add declare-styleable
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Font">
<attr name="typeface">
<enum name="FuturaLT" value="0" />
<enum name="FuturaLT_Heavy" value="1" />
<enum name="FuturaLT_Light" value="2" />
</attr>
</declare-styleable>
</resources>
//Here FuturaLT/FuturaLT_Heavy/FuturaLT_Light are file names
Note: – enum name should be font type name with underscore(_) uses, it will be easy for you to understand font family usage in your native code. No special character or other letter, otherwise you will got error in gen folder for same attribute id.
Step 3: Create your custom view(Button, TextView, EditText) class:-
package com.myapp.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.widget.TextView;
import com.myapp.R;
public class CustomTextView extends TextView {
public CustomTextView(Context context) {
super(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
try {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Font);
int font = a.getInt(R.styleable.Font_typeface, 0);
a.recycle();
String str;
switch (font) {
case 1:
str = "fonts/FuturaLT.otf";
break;
case 2:
str = "fonts/FuturaLT_Heavy.otf";
break;
case 3:
str = "fonts/FuturaLT_Light.otf";
break;
default:
str = "fonts/FuturaLT.otf";
break;
}
setTypeface(FontManager.getInstance(getContext()).loadFont(str));
} catch (Exception e) {
e.printStackTrace();
}
}
#SuppressWarnings("unused")
private void internalInit(Context context, AttributeSet attrs) {
}
}
Step 4: Add FontManager.java support class
package com.myapp.views;
import android.content.Context;
import android.graphics.Typeface;
import java.util.HashMap;
import java.util.Map;
public class FontManager {
private Map<String, Typeface> fontCache = new HashMap<String, Typeface>();
private static FontManager instance = null;
private Context mContext;
private FontManager(Context mContext2) {
mContext = mContext2;
}
public synchronized static FontManager getInstance(Context mContext) {
if (instance == null) {
instance = new FontManager(mContext);
}
return instance;
}
public Typeface loadFont(String font) {
if (false == fontCache.containsKey(font)) {
fontCache.put(font, Typeface.createFromAsset(mContext.getAssets(), font));
}
return fontCache.get(font);
}
}
Step 5: Usage in XML layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.myapp.views.CustomTextView
android:id="#+id/tv_time_slot"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
app:typeface="FuturaLT" />
</LinearLayout>
You can also use in java code directly:
Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/FuturaLT.ttf");
tvText.setTypeface(tf);
Note:- If you don't use here FontManager to apply typeface and directly use
then you are not able to see your views in graphics preview.
I'm trying to put the custom XML namespace in the styles.xml and inherit it in the layout. I don't know how to declare the custom XML namespace in the styles.xml as I do in layout xml (e.g. xmlns:app="http://schemas.android.com/tools").
How do I use custom XML namespace in the styles.xml?
What I have:
The font asset, ReallyCoolFont.ttf is saved in the asset/fonts.
my_layout.xml:
<TextView
<!-- more attributes here -->
app:customFont="fonts/ReallyCoolFont.ttf"
<!-- more attributes here -->
</TextView>
styles.xml:
<style name="CoolTextView">
<!-- more items here -->
<!-- more items here -->
</style>
What I'd like to have:
my_layout.xml:
<TextView
<!-- more attributes here -->
style="#style/CoolTextView
<!-- more attributes here -->
</TextView>
styles.xml:
<style name="CoolTextView">
<!-- more items here -->
<item name="app:customFont">ReallyCoolFont.ttf</item>
<!-- more items here -->
</style>
Error I get:
Error:(1403, 21) No resource found that matches the given name: attr 'app:customFont'.
You need to define an attribute for your fonts in attr.xml file in res folder:
<attr name="myfonts" format="string" />
And you need to define custom style for your TextView and here we use our defined attribute(myfonts):
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
Then styles can be declared:
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
summary of what you have so far:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="myfonts" format="string">
</attr>
<declare-styleable name="MyCustomStyle">
<attr name="myfonts" />
</declare-styleable>
<style name="CoolTextView">
<item name="myfonts">ReallyCoolFont.ttf</item>
</style>
</resources>
4)Now your layout would be:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.MyCustomTextView
android:id="#+id/result"
style="#style/CoolTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="HELLO WORLD!"
android:textSize="24dp"
android:gravity="center" >
</com.example.MyCustomTextView>
</RelativeLayout>
5)and your MyCustomTextView is:
public class MyCustomTextView extends TextView {
private static final String TAG = "TextView";
public MyCustomTextView(Context context) {
super(context);
}
public MyCustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
settingFont(context, attrs);
}
public MyCustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
settingFont(context, attrs);
}
private void settingFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.MyCustomStyle);
String customFont = a.getString(R.styleable.MyCustomStyle_myfonts);
Typeface tf = null;
try {
tf = Typeface.createFromAsset(ctx.getAssets(), customFont);
} catch (Exception e) {
Log.e(TAG,e.getMessage());
a.recycle();
return;
}
setTypeface(tf);
a.recycle();
}
}
I assumed you put the font in asset not in asset/fonts directory.
also I highly recommend read this.
You don't need to add any prefix to reference your custom attributes in the style resource files. Doing it like this will work just fine:
<style name="CoolTextView">
<item name="customFont">ReallyCoolFont.ttf</item>
</style>
The answer is to NOT specify the namespace in the style.
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:custom="http://schemas.android.com/apk/res/com.custom.project">
<style name="CustomStyle">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="customAttr">value</item> <!-- tee hee -->
</style>
</resources>
You don't need any prefixes, it will work without them. This is code from one of my projects, which works just fine
<style name="defaultTriangle">
<item name="triangleColor">#FF33B5E5</item>
<item name="triangleStrokeColor">#android:color/black</item>
<item name="triangleStrokeWidth">3dp</item>
</style>
<si.kseneman.views.Triangle
style="#style/defaultTriangle"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
android:padding="10dp"
android:rotation="0"
/>
I've done next for custom font
CustomTextView
public class KlavikaTextView extends TextView {
private final static int KLAVIKA_BOLD = 0;
private final static int KLAVIKA_BOLD_ITALIC = 1;
private final static int KLAVIKA_LIGHT = 2;
private final static int KLAVIKA_LIGHT_ITALIC = 3;
private final static int KLAVIKA_MEDIUM = 4;
private final static int KLAVIKA_MEDIUM_ITALIC = 5;
private final static int KLAVIKA_REGULAR = 6;
private final static int KLAVIKA_REGULAR_ITALIC = 7;
public KlavikaTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
parseAttributes(context, attrs);
}
public KlavikaTextView(Context context, AttributeSet attrs) {
super(context, attrs);
parseAttributes(context, attrs);
}
public KlavikaTextView(Context context) {
super(context);
}
private void parseAttributes(Context context, AttributeSet attrs) {
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.KlavikaTextView);
// The value 0 is a default, but shouldn't ever be used since the attr is an enum
int typeface = values.getInt(R.styleable.KlavikaTextView_typeface, KLAVIKA_REGULAR);
// You can instantiate your typeface anywhere, I would suggest as a
// singleton somewhere to avoid unnecessary copies
switch (typeface) {
case KLAVIKA_BOLD:
setTypeface(App.klavikaBold);
break;
case KLAVIKA_BOLD_ITALIC:
setTypeface(App.klavikaBoldItalic);
break;
case KLAVIKA_LIGHT:
setTypeface(App.klavikaLight);
break;
case KLAVIKA_LIGHT_ITALIC:
setTypeface(App.klavikaLightItalic);
break;
case KLAVIKA_MEDIUM:
setTypeface(App.klavikaMedium);
break;
case KLAVIKA_MEDIUM_ITALIC:
setTypeface(App.klavikaMediumItalic);
break;
case KLAVIKA_REGULAR_ITALIC:
setTypeface(App.klavikaRegularItalic);
break;
case KLAVIKA_REGULAR:
default:
setTypeface(App.klavikaRegular);
break;
}
}}
Then in values I've created attr.xml
<!-- Define the values for the attribute -->
<attr name="typeface" format="enum">
<enum name="klavika_bold" value="0" />
<enum name="klavika_bold_italic" value="1" />
<enum name="klavika_light" value="2" />
<enum name="klavika_light_italic" value="3" />
<enum name="klavika_medium" value="4" />
<enum name="klavika_medium_italic" value="5" />
<enum name="klavika_regular" value="6" />
<enum name="klavika_regular_italic" value="7" />
</attr>
<!--
Tell Android that the class "KlavikaTextView" can be styled,
and which attributes it supports-->
<declare-styleable name="KlavikaTextView">
<attr name="typeface" />
</declare-styleable>
Next created the style
<style name="TextView.Example">
<item name="typeface">klavika_bold</item>
</style>
This style you can use for your xml Layouts
style="#style/TextView.Example"
<?xml version="1.0" encoding="utf-8"?>
<resources
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res/com.my.project">
<style name="my_style"> <item name="custom:tag">some_value</item> </style>
</resources>
you are trying to apply XML namespacing to an attribute value, which won't work. In this case, you should specify the package name directly, like this:
<style name="my_style"> <item name="com.my.project:tag">some_value</item> </style>
Fast solution via code!
String pathFont = "fonts/ReallyCoolFont.ttf";
TextView text = (TextView) findViewById(R.id.TextView1);
Typeface fontFace = Typeface.createFromAsset( getAssets(), pathFont );
text.setTypeface( fontFace );
Third-party libraries , solve the problem, in XML!
1 - https://github.com/leok7v/android-textview-custom-fonts
2 - https://github.com/ragunathjawahar/android-typeface-textview
My suggestion
You will have other needs, and for each component
you will have to customize a class.
Another problem you have other layouts and N TextView components
for maintenance you will have a lot of work .
I use this method in projects in the OnCreate of my activity
if I need to change the font I have to do this
only in the OnCreate method of each activity .
private static final String FONT = "ReallyCoolFont.ttf";
public static void allTextView(final Context context, final View root) {
String fontPath = FONT;
try {
if (root instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) root;
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++)
allTextView(context, viewGroup.getChildAt(i) );
} else if (root instanceof TextView)
((TextView) root).setTypeface(Typeface.createFromAsset(context.getAssets(), fontPath));
} catch (Exception e) {
e.printStackTrace();
}
}
// call in OnCreate Activity
allTextView(this, findViewById(R.layout.main) );
The custom attributes are defined using <declare-styleable> tags; usually the file is called attrs.xml. The namespace declaration will have your app's package name in it.
The whole process is described here: Creating a View Class | Android Developers