Вопрос или проблема
Как использовать пользовательские шрифты для текста в уведомлениях на Android? Я пробовал создать папку “font” и добавить файл font.ttf в “font/file_name.ttf”, но это не сработало. Я хочу изменить шрифт текста в уведомлениях по умолчанию.вставьте описание изображения здесь
MainActivity.kt
class MainActivity: FlutterActivity() {
private val CHANNEL = "flutter.native/helper"
private lateinit var mediaSession: MediaSessionCompat
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
mediaSession = MediaSessionCompat(this, "MediaSession")
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"showNotificationFromNative" -> {
val title = call.argument("title") ?: "Пусто"
val message = call.argument("message") ?: "Пусто"
val greetings = showSimpleNotification(title, message)
result.success(greetings)
}
"showCustomNotificationFromNative" -> {
val args = call.arguments as? Map
if (args != null) {
val greetings = showCustomNotification(args)
result.success(greetings)
} else {
result.error("INVALID_ARGUMENTS", "Аргументы должны быть Map", null)
}
}
"showMediaNotification" -> {
val title = call.argument("title") ?: ""
val artist = call.argument("artist") ?: ""
val album = call.argument("album") ?: ""
val duration = call.argument("duration") ?: 0
val position = call.argument("position") ?: 0
showMediaNotification(title, artist, album, duration, position)
result.success(null)
}
else -> {
result.notImplemented()
}
}
}
}
private fun showCustomNotification(args: Map): String {
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "i.apps.custom.notification"
val description = "Пользовательское уведомление о зарядке"
val isFirstUpdate = args["is_first_update"] as Boolean
val isStillCharging = args["isStillCharging"] as Boolean
// Создание и настройка канала уведомлений
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isFirstUpdate) {
val notificationChannel = NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(false)
notificationManager.createNotificationChannel(notificationChannel)
}
// Создание уведомления
val builder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_charging_small)
.setOngoing(isStillCharging)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setContentTitle("${args["device_name"]}")
.setContentText("${args["current_percentage"]}% / ${args["estimate_percentage"]}% к ${args["estimate_time"]}")
// Добавление индикатора выполнения
val maxProgress = args["estimate_percentage"].toString().toInt()
val currentProgress = args["current_percentage"].toString().toInt()
// Создание пользовательского макета
val customLayout = RemoteViews(packageName, R.layout.notification_expanded)
customLayout.setTextViewText(R.id.charging_title, "${args["device_name"]}")
customLayout.setTextViewText(R.id.charging_estimate, "${args["estimate_percentage"]}% к ${args["estimate_time"]}")
customLayout.setProgressBar(R.id.charging_progress, maxProgress, currentProgress, false)
customLayout.setTextViewText(R.id.charging_percentage, "${args["current_percentage"]}%")
// Установка пользовательского макета
builder.setCustomBigContentView(customLayout)
builder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
// builder.setStyle(MediaStyle())
// Показать уведомление
notificationManager.notify(12345, builder.build())
return "Успешно"
}
файл для макета и UI -> “res/layout/notification_expanded.xml”
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:background="@drawable/charging_background_image_dark">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:paddingTop="12dp"
android:paddingBottom="12dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:layout_width="16dp"
android:layout_height="16dp"
android:layout_gravity="center"
android:src="@drawable/ic_charging"
android:tint="#FFFFFF" />
<TextView
android:id="@+id/charging_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="0dp"
android:text="Зарядка"
android:fontFamily="@font/conigen"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:textStyle="bold" />
<TextView
android:id="@+id/charging_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="8dp"
android:text="Raptrix"
android:textColor="#08999F"
android:textSize="20sp"
android:textStyle="bold|italic" />
</LinearLayout>
<TextView
android:id="@+id/charging_estimate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="80% к 9:30 AM"
android:layout_gravity="center|right"
android:textColor="#FFFFFF"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
Я хочу решение для настройки семейства шрифтов в тексте внутри уведомления.
Ответ или решение
Чтобы настроить семейство шрифтов текста в пользовательском уведомлении Android с использованием NotificationCompat.DecoratedCustomViewStyle()
, вы можете следовать нижеуказанным шагам. Хочу обратить ваше внимание, что для кастомизации шрифта в системных уведомлениях использовать шрифты не так просто, как в обычных элементах UI. Однако, используя RemoteViews
, мы можем установить кастомные шрифты в текстовые поля уведомления.
Шаги для настройки шрифта уведомления
-
Добавление шрифта в проект:
Убедитесь, что вы добавили свой шрифт (.ttf или .otf файл) в папкуres/font
. Например, если ваш шрифт называетсяconigen.ttf
, путь будет выглядеть так:res/font/conigen.ttf
. -
Использование
RemoteViews
:
В вашем коде, при создании пользовательского уведомления, вы должны использоватьRemoteViews
для настройки вашего пользовательского макета. Однако, нужно помнить, что Android не поддерживает установку пользовательских шрифтов через XML дляRemoteViews
. Вместо этого вам нужно делать это программно.
Изменение кода для установки пользовательского шрифта
В вашем методе showCustomNotification
, вы должны загрузить шрифт программно и установить его для текстовых полей. Вот как это можно сделать:
private fun showCustomNotification(args: Map<String, Any>): String {
val notificationManager: NotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channelId = "i.apps.custom.notification"
val description = "Custom Charging Notification"
val isFirstUpdate = args["is_first_update"] as Boolean
val isStillCharging = args["isStillCharging"] as Boolean
// Создание и настройка канала уведомлений
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && isFirstUpdate) {
val notificationChannel = NotificationChannel(channelId, description, NotificationManager.IMPORTANCE_HIGH)
notificationChannel.enableLights(true)
notificationChannel.lightColor = Color.GREEN
notificationChannel.enableVibration(false)
notificationManager.createNotificationChannel(notificationChannel)
}
// Создание уведомления
val builder = NotificationCompat.Builder(this, channelId)
.setSmallIcon(R.drawable.ic_charging_small)
.setOngoing(isStillCharging)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
// Создание пользовательского макета
val customLayout = RemoteViews(packageName, R.layout.notification_expanded)
customLayout.setTextViewText(R.id.charging_title, "${args["device_name"]}")
customLayout.setTextViewText(R.id.charging_estimate, "${args["estimate_percentage"]}% by ${args["estimate_time"]}")
customLayout.setTextViewText(R.id.charging_percentage, "${args["current_percentage"]}%")
// Установка шрифта программно
val typeface = ResourcesCompat.getFont(this, R.font.conigen) // загрузка шрифта
customLayout.setTextViewTypeface(R.id.charging_title, typeface)
customLayout.setTextViewTypeface(R.id.charging_estimate, typeface)
customLayout.setTextViewTypeface(R.id.charging_percentage, typeface)
// Установка пользовательского макета
builder.setCustomBigContentView(customLayout)
builder.setStyle(NotificationCompat.DecoratedCustomViewStyle())
// Показ уведомления
notificationManager.notify(12345, builder.build())
return "Success"
}
Обратите внимание:
-
Метод
setTextViewTypeface
вRemoteViews
не является стандартным методом, его нужно создать, используя reflection или другие подходы, поскольку в стандартной библиотеке Android нет прямой поддержки установки типографики черезRemoteViews
. Поэтому вам будет необходимо создать свой способ или использовать сторонние библиотеки для этого. -
В разных версиях Android поддержка шрифтов в уведомлениях может отличаться. Тестируйте ваше решение на разных устройствах.
Заключение
Таким образом, настройка шрифтов в уведомлениях является сложной задачей и требует определённых обходных путей. Используя подход, описанный выше, вы сможете добиться желаемого результата, но будьте готовы к дополнительным испытаниям с функциональностью шрифтов в зависимости от версии устройства Android и его интерфейса уведомлений.