如果我从代码(在特定设备上)创建 TextView,为什么字体不适用
Why fonts don't apply if I create TextView from code (on specific devices)
我将项目中的字体更改为自定义字体。它在模拟器和许多设备上工作正常,但在某些设备上它在某些情况下不起作用,例如,当我从代码创建 TextView 时。
我有一个演示此问题的示例项目。
这是我的样式文件
<resources>
<style name="TextStyle.Caption" parent="TextAppearance.AppCompat.Caption">
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">@font/eesti_pro_display_bold</item>
<item name="android:letterSpacing">0.03</item>
</style>
</resources>
这是我的xml。这里我有 TextView 和 textAppearance
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textAppearance="@style/TextStyle.Caption"/>
</androidx.constraintlayout.widget.ConstraintLayout>
我的 Activity 我在其中创建了另一个 TextView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val layout: ConstraintLayout = findViewById(R.id.container)
createItemTitleTextView(this.baseContext).apply {
layout.addView(this)
text = "Hello World from code!"
}
}
}
private fun createItemTitleTextView(context: Context) = TextView(context).apply {
TextViewCompat.setTextAppearance(this, R.style.TextStyle_Caption)
}
模拟器结果(预期结果):
Samsung Galaxy J5 的结果。斜体字体为 Galaxy 系统字体。 请注意,我的字体来自 xml,但不是来自代码
编辑
我知道我可以使用 setTypeface 并且一切都按预期工作,但我想知道为什么 setTextAppearance 不起作用。因为我只想更改我的样式文件,而不是整个项目,并从代码
向每个 TextView 添加 setTypeface
在Android8.0之前,fontFamily
只支持默认值:
android:fontFamily="sans-serif" // roboto regular
android:fontFamily="sans-serif-light" // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-thin" // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium" // roboto medium (android 5.0)
https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml
自定义字体需要下载ttf文件,使用方法如下:
Typeface typeface = Utils.getTypeface(context, textStyle);
if (typeface != null) setTypeface(typeface);
Utils文件中的函数为:
public static Typeface getTypeface(Context context, int textStyle) {
try {
String font = "fonts/font-file-name.ttf"
Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), font);
return myTypeface;
} catch (Exception e) {
Log.d(Constants.TAG, "OpenSansTextView init: ");
e.printStackTrace();
}
return null;
}
我的 ttf 文件的位置:
app\src\main\assets\fonts\font-file-name.ttf
编辑(备用解决方案):
如果您已经有太多无法在 java 中到处添加 "setTypeface" 的 TextView,
然后,只需按 Ctrl + Shift + R
并将 <TextView
替换为 <com.your.package.app.MyTextView
。
您可以将自定义 TextView 创建为:
package com.your.package.app;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
public class MyTextView extends android.support.v7.widget.AppCompatTextView {
Context context;
Integer textStyle = 0;
String textOS;
public MyTextView(Context context) {
super(context);
this.context = context;
init(null);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init(attrs);
}
public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
init(attrs);
}
private void init(AttributeSet attrs) {
try {
String font = "fonts/font-file-name.ttf"
Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), font);
if (typeface != null) setTypeface(typeface);
} catch (Exception e) {
Log.d(Constants.TAG, "MyTextView init: ");
e.printStackTrace();
}
}
}
TextViewCompat.setTextAppearance(tv, R.style.TextStyle_Caption)
不起作用,因为我创建了 TextView。但是,我需要创建 AppCompatTextView 并且一切都按预期工作
我将项目中的字体更改为自定义字体。它在模拟器和许多设备上工作正常,但在某些设备上它在某些情况下不起作用,例如,当我从代码创建 TextView 时。
我有一个演示此问题的示例项目。
这是我的样式文件
<resources>
<style name="TextStyle.Caption" parent="TextAppearance.AppCompat.Caption">
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">@font/eesti_pro_display_bold</item>
<item name="android:letterSpacing">0.03</item>
</style>
</resources>
这是我的xml。这里我有 TextView 和 textAppearance
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:textAppearance="@style/TextStyle.Caption"/>
</androidx.constraintlayout.widget.ConstraintLayout>
我的 Activity 我在其中创建了另一个 TextView
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val layout: ConstraintLayout = findViewById(R.id.container)
createItemTitleTextView(this.baseContext).apply {
layout.addView(this)
text = "Hello World from code!"
}
}
}
private fun createItemTitleTextView(context: Context) = TextView(context).apply {
TextViewCompat.setTextAppearance(this, R.style.TextStyle_Caption)
}
模拟器结果(预期结果):
Samsung Galaxy J5 的结果。斜体字体为 Galaxy 系统字体。 请注意,我的字体来自 xml,但不是来自代码
编辑
我知道我可以使用 setTypeface 并且一切都按预期工作,但我想知道为什么 setTextAppearance 不起作用。因为我只想更改我的样式文件,而不是整个项目,并从代码
向每个 TextView 添加 setTypeface在Android8.0之前,fontFamily
只支持默认值:
android:fontFamily="sans-serif" // roboto regular
android:fontFamily="sans-serif-light" // roboto light
android:fontFamily="sans-serif-condensed" // roboto condensed
android:fontFamily="sans-serif-thin" // roboto thin (android 4.2)
android:fontFamily="sans-serif-medium" // roboto medium (android 5.0)
https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml
自定义字体需要下载ttf文件,使用方法如下:
Typeface typeface = Utils.getTypeface(context, textStyle);
if (typeface != null) setTypeface(typeface);
Utils文件中的函数为:
public static Typeface getTypeface(Context context, int textStyle) {
try {
String font = "fonts/font-file-name.ttf"
Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), font);
return myTypeface;
} catch (Exception e) {
Log.d(Constants.TAG, "OpenSansTextView init: ");
e.printStackTrace();
}
return null;
}
我的 ttf 文件的位置:
app\src\main\assets\fonts\font-file-name.ttf
编辑(备用解决方案):
如果您已经有太多无法在 java 中到处添加 "setTypeface" 的 TextView,
然后,只需按 Ctrl + Shift + R
并将 <TextView
替换为 <com.your.package.app.MyTextView
。
您可以将自定义 TextView 创建为:
package com.your.package.app;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
public class MyTextView extends android.support.v7.widget.AppCompatTextView {
Context context;
Integer textStyle = 0;
String textOS;
public MyTextView(Context context) {
super(context);
this.context = context;
init(null);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
init(attrs);
}
public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.context = context;
init(attrs);
}
private void init(AttributeSet attrs) {
try {
String font = "fonts/font-file-name.ttf"
Typeface myTypeface = Typeface.createFromAsset(context.getAssets(), font);
if (typeface != null) setTypeface(typeface);
} catch (Exception e) {
Log.d(Constants.TAG, "MyTextView init: ");
e.printStackTrace();
}
}
}
TextViewCompat.setTextAppearance(tv, R.style.TextStyle_Caption)
不起作用,因为我创建了 TextView。但是,我需要创建 AppCompatTextView 并且一切都按预期工作