android - 将自定义字体设置为对话框
问题描述
我们正在尝试将对话框的标题设置为具有自定义字体,因此我们尝试使用以下内容制作主题:
<style name="DialogTheme" parent="Theme.AppCompat.Dialog.Alert">
<item name="android:windowTitleStyle">@style/Dialog.Title</item>
</style>
<style name="Dialog.Title" parent="RtlOverlay.DialogWindowTitle.AppCompat">
<item name="android:textAppearance">@style/Dialog.TextAppearance.Title</item>
</style>
<style name="Dialog.TextAppearance.Title" parent="TextAppearance.AppCompat.Title">
<item name="fontFamily">@font/custom_font</item>
</style>
我们正在创建这样的对话框构建器:
AlertDialog.Builder(ContextThemeWrapper(context, R.style.DialogTheme), R.style.DialogTheme)
样式和文本外观被完全忽略。对于其他样式,它似乎正在工作。
AppCompat
我们设法通过复制使用的布局并将其添加为自定义标题来使其工作:
<?xml version="1.0" encoding="utf-8"?>
<!-- modified from AppCompat's abc_alert_dialog_title_material.xml -->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|start|left"
android:paddingLeft="?attr/dialogPreferredPadding"
android:paddingRight="?attr/dialogPreferredPadding"
android:paddingTop="@dimen/abc_dialog_padding_top_material">
<TextView
android:id="@+id/alertTitle"
style="@style/Dialog.Title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textAlignment="viewStart"
tools:text="Some title" />
</FrameLayout>
基于此:abc_alert_dialog_title_material.xml
DialogTitle
我们在这里使用的是TextView
. 什么DialogTitle
是使用以下内容重载 onMeasure:
final Layout layout = getLayout();
if (layout != null) {
final int lineCount = layout.getLineCount();
if (lineCount > 0) {
final int ellipsisCount = layout.getEllipsisCount(lineCount - 1);
if (ellipsisCount > 0) {
setSingleLine(false);
setMaxLines(2);
final TypedArray a = getContext().obtainStyledAttributes(null,
R.styleable.TextAppearance,
android.R.attr.textAppearanceMedium,
android.R.style.TextAppearance_Medium);
final int textSize = a.getDimensionPixelSize(
R.styleable.TextAppearance_android_textSize, 0);
if (textSize != 0) {
// textSize is already expressed in pixels
setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
}
a.recycle();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
}
我们认为它与设置文本大小有关,但我们不确定。我们有一个有效的技巧(使用复制的布局)。但是,我们更愿意知道如何使它与 xml 样式和主题一起工作,而不必更改默认行为。
解决方案
从我对我最近发布的另一个问题的回答来看,这就是我能够以编程方式设置AlertDialog
. 希望对你有效。
Typeface semibold = ResourcesCompat.getFont(this, R.font.product_bold);
Typeface regular = ResourcesCompat.getFont(this, R.font.product_regular);
AlertDialog myDialog = new AlertDialog.Builder(this).setTitle("Your title")
.setMessage("Your message.")
.setPositiveButton("Your button", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//your code
}
}).show();
int titleText = getResources().getIdentifier("alertTitle", "id", "android");
((TextView) myDialog.getWindow().findViewById(titleText)).setTypeface(semibold);
TextView dialogMessage = myDialog.getWindow().findViewById(android.R.id.message);
Button dialogButton = myDialog.getWindow().findViewById(android.R.id.button1);
dialogMessage.setTypeface(regular);
dialogButton.setTypeface(semibold);
确认在 Android 9.0 上工作,不能声称它可以在旧 API 上工作。
另一种使用 TextView 以编程方式设置标题的方法,这就是我以前的做法:
TextView alertTitle = findViewById(R.id.alertTextTemp);
if (alertTitle.getParent() != null) {
((ViewGroup) alertTitle.getParent()).removeView(alertTitle);
}
alertTitle.setText("Warning");
alertTitle.setVisibility(View.VISIBLE);
alertTitle.setTypeface(semibold);
然后,当您创建对话框时,您可以设置自定义标题:
new AlertDialog.Builder(MainActivity.this).setCustomTitle(alertTitle)...
alertTitle 是您activity_main.xml
文件中的 TextView:
<TextView
android:id="@+id/alertTextTemp"
android:visibility="gone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="22sp"
android:paddingLeft="23dp"
android:paddingTop="22dp"
android:textColor="#000000" />
我必须微调 TextView 上的这些属性以使其尽可能接近默认标题边距和大小,您可能需要验证它是否适合您。
推荐阅读
- javascript - 我该怎么做才能使“摇滚,纸,剪刀”发挥作用?
- bash - Curl 获取 HTTP 响应 0 而不是 200
- python - Python SVD 修复特征值的数量以重建图像?
- c++ - 如何设置范围以提取我想要获取的信息?
- swift - 如何将 PDF 文件上传到已经在内存中的 firebase
- c# - C# DataGridView 不必要的左列
- python - Scipy fmin_cg 没有迭代
- javascript - (承诺/异步):Vue 组件中的“TypeError: Object(...) is not a function”
- node.js - 使用相同框架分发模块的最佳方式
- jenkins - Jenkins 环境变量条件集