Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Font gets changed in Android Studio preview but not in the Emulator/device

I'm trying to change the default font of textviews, checkbox, buttons and android.support.design.widget.TextInputLayout. For clear illustration, I set "android:fontFamily">cursive<.

It seems to appear correctly in Android Studio preview but not in the Emulator, as shown below. Also note, that password (hint) does not seems to work in both. Would appreciate your help to highlight why this is happening.

enter image description here

styles.xml:

<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textColor">#ed328b</item>
    <item name="android:titleTextColor">#ed328b</item>
    <item name="android:textSize">14sp</item>
    <item name="android:fontFamily">cursive</item>
</style>

<style name="TextLabel" parent="Widget.Design.TextInputLayout">
    <!-- Hint color and label color in FALSE state -->
    <item name="android:textColorHint">#ed328b</item>
    <item name="android:textSize">14sp</item>
    <!-- Label color in TRUE state and bar color FALSE and TRUE State -->
    <item name="colorAccent">#ed328b</item>
    <item name="android:textColor">#ed328b</item>
    <item name="colorControlNormal">#ed328b</item>
    <item name="colorControlActivated">#ed328b</item>
    <item name="android:textColorSecondary">#ed328b</item>
    <item name="android:textColorPrimary">#ed328b</item>
    <item name="android:fontFamily">cursive</item>
</style>

activity_main.xml:

<android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/TextLabel"
            android:layout_marginTop="@dimen/space_2">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:inputType="textEmailAddress"
                android:hint="@string/signin_emailaddress"
                android:id="@+id/txtEmail" />
        </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:theme="@style/TextLabel"
            android:layout_marginTop="@dimen/space_2">
            <EditText
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginBottom="10dp"
                android:inputType="textPassword"
                android:hint="@string/signin_password"
                android:id="@+id/txtPassword" />
        </android.support.design.widget.TextInputLayout>

        <CheckBox
            android:id="@+id/rememberBox"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:layout_gravity="start"
            android:text="remember my email and password"
            android:textAlignment="center"
            android:textColor="#ed328b"
            android:textSize="11dp" />
like image 345
aj888 Avatar asked Feb 13 '18 05:02

aj888


Video Answer


4 Answers

While selecting the Font in the Android Studio, just check the box "Add font to Project" rather choosing "create downloadable Font".

Your problem will be solved.

Android Resources Window

like image 121
Avinesh Sharma Avatar answered Oct 22 '22 12:10

Avinesh Sharma


Android doesn't have built-in support for applying custom fonts directly to text widgets through XML.

You can refer this document to set fonts in xml: https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

Or you need to set typeface in java code in order to change fonts.

Or you can do something like this:

First

You'll need to define your own stylable. In your /res/values folder, open/create the attrs.xml file and add a declare-styleable object like so:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="FontText">
        <attr name="typefaceAsset" format="string"/>
    </declare-styleable>
</resources>

Second

Assuming you want to use this widget often, you should set up a simple cache for the loaded Typeface objects, since loading them from memory on the fly can take time. Something like:

public class FontManager {
    private static FontManager instance;

    private AssetManager mgr;

    private Map<String, Typeface> fonts;

    private FontManager(AssetManager _mgr) {
        mgr = _mgr;
        fonts = new HashMap<String, Typeface>();
    }

    public static void init(AssetManager mgr) {
        instance = new FontManager(mgr);
    }

    public static FontManager getInstance() {
        if (instance == null) {
            // App.getContext() is just one way to get a Context here
            // getContext() is just a method in an Application subclass
            // that returns the application context
            AssetManager assetManager = App.getContext().getAssets();
            init(assetManager);
        }
        return instance;
    }

    public Typeface getFont(String asset) {
        if (fonts.containsKey(asset))
            return fonts.get(asset);

        Typeface font = null;

        try {
            font = Typeface.createFromAsset(mgr, asset);
            fonts.put(asset, font);
        } catch (Exception e) {

        }

        if (font == null) {
            try {
                String fixedAsset = fixAssetFilename(asset);
                font = Typeface.createFromAsset(mgr, fixedAsset);
                fonts.put(asset, font);
                fonts.put(fixedAsset, font);
            } catch (Exception e) {

            }
        }

        return font;
    }

    private String fixAssetFilename(String asset) {
        // Empty font filename?
        // Just return it. We can't help.
        if (TextUtils.isEmpty(asset))
            return asset;

        // Make sure that the font ends in '.ttf' or '.ttc'
        if ((!asset.endsWith(".ttf")) && (!asset.endsWith(".ttc")))
            asset = String.format("%s.ttf", asset);

        return asset;
    }
}

This one will allow you to use .ttc file extensions, but it's untested.

Third

Create a new class that subclasses TextView. This particular example takes into account the defined XML typeface (bold, italic, etc.) and apply it to the font (assuming you're using a .ttc file).

/**
 * TextView subclass which allows the user to define a truetype font file to use as the view's typeface.
 */
public class FontText extends TextView {
    public FontText(Context context) {
        this(context, null);
    }

    public FontText(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FontText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        if (isInEditMode())
            return;

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.FontText);

        if (ta != null) {
            String fontAsset = ta.getString(R.styleable.FontText_typefaceAsset);

            if (!TextUtils.isEmpty(fontAsset)) {
                Typeface tf = FontManager.getInstance().getFont(fontAsset);
                int style = Typeface.NORMAL;
                float size = getTextSize();

                if (getTypeface() != null)
                    style = getTypeface().getStyle();

                if (tf != null)
                    setTypeface(tf, style);
                else
                    Log.d("FontText", String.format("Could not create a font from asset: %s", fontAsset));
            }
        }
    }
}

Finally at last

Replace the instances of TextView in your XML with the fully qualified class name. Declare your custom namespace just like you would the Android namespace. Note that the "typefaceAsset" should point to a .ttf or .ttc file contained in your /assets directory.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.example.FontText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This is a custom font text"
        custom:typefaceAsset="fonts/AvenirNext-Regular.ttf"/>
</RelativeLayout>
like image 36
Jay Patel Avatar answered Oct 22 '22 11:10

Jay Patel


Make sure your "super.onCreate(savedInstanceState)" is in the first line.

 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity);
 }

If you put the lines in the wrong order. Ex:

 @Override
 protected void onCreate(@Nullable Bundle savedInstanceState) {
    setContentView(R.layout.activity);
    super.onCreate(savedInstanceState);
 }

... then Android Studio preview will show the font correctly but in the Emulator/device it will fail.

like image 24
Fernando Roldan Avatar answered Oct 22 '22 11:10

Fernando Roldan


It happened with me also, I was using an huawei honor 7c device there I have selected a different font for my entire phone. So that's why it was not reflecting in my real device

So try setting the default font from the phone settings and see it should work.

like image 2
Sanket Bhangale Avatar answered Oct 22 '22 10:10

Sanket Bhangale