字体在 Android Studio 预览中更改,但在模拟器/设备中未更改 [英] Font gets changed in Android Studio preview but not in the Emulator/device

查看:33
本文介绍了字体在 Android Studio 预览中更改,但在模拟器/设备中未更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试更改文本视图、复选框、按钮和 android.support.design.widget.TextInputLayout 的默认字体.为了清楚地说明,我设置了android:fontFamily">草书<.

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<.

它似乎在 Android Studio 预览中正确显示,但在模拟器中却没有,如下所示.另请注意,密码(提示)似乎不适用于两者.感谢您的帮助,以强调为什么会发生这种情况.

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.

styles.xml:

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:

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" />

推荐答案

Android 没有内置支持通过 XML 将自定义字体直接应用于文本小部件.

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

你可以参考这个文档在xml中设置字体:https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html

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

或者你需要在java代码中设置字体才能改变字体.

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

或者你可以这样做:

第一

您需要定义自己的样式.在您的/res/values 文件夹中,打开/创建 attrs.xml 文件并添加一个声明样式的对象,如下所示:

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>

第二

假设您想经常使用这个小部件,您应该为加载的字体对象设置一个简单的缓存,因为从内存中动态加载它们可能需要时间.类似的东西:

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;
    }
}

这将允许您使用 .ttc 文件扩展名,但它未经测试.

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

第三

创建一个子类化 TextView 的新类.此特定示例考虑了定义的 XML 字体(粗体、斜体等)并将其应用于字体(假设您使用的是 .ttc 文件).

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));
            }
        }
    }
}

终于来了

用完全限定的类名替换 XML 中的 TextView 实例.像声明 Android 命名空间一样声明您的自定义命名空间.请注意,typefaceAsset"应指向/assets 目录中包含的 .ttf 或 .ttc 文件.

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>

这篇关于字体在 Android Studio 预览中更改,但在模拟器/设备中未更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆