Android Studio 预览中的字体已更改,但 Emulator/device 中未更改
Font gets changed in Android Studio preview but not in the Emulator/device
我正在尝试更改文本视图、复选框、按钮和 android.support.design.widget.TextInputLayout 的默认字体。为了清楚说明,我设置了 "android:fontFamily">cursive<。
它似乎在 Android Studio 预览中正确显示,但在模拟器中却不正确,如下所示。另请注意,密码(提示)似乎不适用于两者。感谢您帮助强调为什么会发生这种情况。
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" />
尝试
editText.setTypeface(Typeface.SERIF);
或
// Create a TypeFace using font from Assets folder
Typeface mtypeFace = Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf");
// set TypeFace to the TextView or Edittext
tvText.setTypeface(mtypeFace);
或 XML
android:fontFamily="@font/yourfont"
source here
Android 不支持通过 XML.
将自定义字体直接应用于文本小部件
xml可以参考此文档设置字体:https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html
或者您需要在 java 代码中设置字体才能更改字体。
或者你可以这样做:
第一
您需要定义自己的样式。在您的 /res/values 文件夹中,open/create attrs.xml 文件并添加一个 declare-styleable 对象,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FontText">
<attr name="typefaceAsset" format="string"/>
</declare-styleable>
</resources>
第二
假设您想经常使用这个小部件,您应该为加载的 Typeface 对象设置一个简单的缓存,因为从内存中动态加载它们需要时间。类似于:
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 文件扩展名,但未经测试。
第三
创建一个新的 class 子class TextView。此特定示例考虑了定义的 XML 字体(粗体、斜体等)并将其应用于字体(假设您使用的是 .ttc 文件)。
/**
* 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 实例替换为完全限定的 class 名称。像声明 Android 命名空间一样声明您的自定义命名空间。请注意,"typefaceAsset" 应指向 /assets 目录中包含的 .ttf 或 .ttc 文件。
<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>
确保你的"super.onCreate(savedInstanceState)"在第一行。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
}
如果你把行放在错误的顺序。例如:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity);
super.onCreate(savedInstanceState);
}
... 然后 Android Studio 预览会正确显示字体,但在 Emulator/device 中会失败。
在 Android Studio 中选择字体时,只需选中复选框 "Add font to Project" 而不是选择 "create downloadable Font"。
你的问题就迎刃而解了。
我也遇到过这种情况,我当时使用的是华为荣耀 7c 设备,我为整个 phone 选择了不同的字体。所以这就是为什么它没有反映在我的真实设备中
因此,请尝试从 phone 设置中设置默认字体,看看它是否有效。
我正在尝试更改文本视图、复选框、按钮和 android.support.design.widget.TextInputLayout 的默认字体。为了清楚说明,我设置了 "android:fontFamily">cursive<。
它似乎在 Android Studio 预览中正确显示,但在模拟器中却不正确,如下所示。另请注意,密码(提示)似乎不适用于两者。感谢您帮助强调为什么会发生这种情况。
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" />
尝试
editText.setTypeface(Typeface.SERIF);
或
// Create a TypeFace using font from Assets folder
Typeface mtypeFace = Typeface.createFromAsset(getAssets(),
"fonts/MyFont.ttf");
// set TypeFace to the TextView or Edittext
tvText.setTypeface(mtypeFace);
或 XML
android:fontFamily="@font/yourfont"
source here
Android 不支持通过 XML.
将自定义字体直接应用于文本小部件xml可以参考此文档设置字体:https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html
或者您需要在 java 代码中设置字体才能更改字体。
或者你可以这样做:
第一
您需要定义自己的样式。在您的 /res/values 文件夹中,open/create attrs.xml 文件并添加一个 declare-styleable 对象,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="FontText">
<attr name="typefaceAsset" format="string"/>
</declare-styleable>
</resources>
第二
假设您想经常使用这个小部件,您应该为加载的 Typeface 对象设置一个简单的缓存,因为从内存中动态加载它们需要时间。类似于:
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 文件扩展名,但未经测试。
第三
创建一个新的 class 子class TextView。此特定示例考虑了定义的 XML 字体(粗体、斜体等)并将其应用于字体(假设您使用的是 .ttc 文件)。
/**
* 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 实例替换为完全限定的 class 名称。像声明 Android 命名空间一样声明您的自定义命名空间。请注意,"typefaceAsset" 应指向 /assets 目录中包含的 .ttf 或 .ttc 文件。
<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>
确保你的"super.onCreate(savedInstanceState)"在第一行。
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
}
如果你把行放在错误的顺序。例如:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
setContentView(R.layout.activity);
super.onCreate(savedInstanceState);
}
... 然后 Android Studio 预览会正确显示字体,但在 Emulator/device 中会失败。
在 Android Studio 中选择字体时,只需选中复选框 "Add font to Project" 而不是选择 "create downloadable Font"。
你的问题就迎刃而解了。
我也遇到过这种情况,我当时使用的是华为荣耀 7c 设备,我为整个 phone 选择了不同的字体。所以这就是为什么它没有反映在我的真实设备中
因此,请尝试从 phone 设置中设置默认字体,看看它是否有效。