Фон
Начиная с Android O, приложения могут иметь адаптивные значки, которые состоят из двух слоев чертежей: переднего плана и фона. Фон - это маска, которая становится формой выбора пусковой установки/пользователя, в то время как ОС также имеет форму по умолчанию.
Вот пример того, что позволяет Nova Launcher:
Как вы можете видеть, это позволяет не только выбирать, какую форму использовать, но и вообще избегать фигуры (в "предпочитайте устаревшие значки" ).
Вот несколько ссылок об этом:
- https://www.youtube.com/watch?v=5MHFYfXno9c
- https://medium.com/@ianhlake/vectordrawable-adaptive-icons-3fed3d3205b5
Проблема
Пока я знаю, как создать экземпляр AdaptiveIconDrawable, и я знаю мастера, который помогает создавая один для текущего приложения, я не понимаю, как, учитывая экземпляр AdaptiveIconDrawable, пусковые установки меняют форму.
Не только это, но я помню, что видел пусковую установку или две, что позволяет не иметь никакой формы.
К сожалению, я не могу найти никакой информации об этой части, возможно, потому что это относительно новая функция. Для StackOverflow нет даже ключевого слова здесь.
Что я пробовал
Я пробовал читать о адаптивных значках, но не мог найти ссылку на сторону приемника.
Я знаю, что в нем есть 2 чертежа:
- https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html#getBackground()
- https://developer.android.com/reference/android/graphics/drawable/AdaptiveIconDrawable.html#getForeground()
Я знаю, по крайней мере, как получить экземпляр AdaptiveIconDrawable из стороннего приложения (при условии, что он есть):
PackageManager pm = context.getPackageManager();
Intent launchIntentForPackage = pm.getLaunchIntentForPackage(packageName);
String fullPathToActivity = launchIntentForPackage.getComponent().getClassName();
ActivityInfo activityInfo = pm.getActivityInfo(new ComponentName(packageName, fullPathToActivity), 0);
int iconRes = activityInfo.icon;
Drawable drawable = pm.getDrawable(packageName, iconRes, activityInfo.applicationInfo); // will be AdaptiveIconDrawable, if the app has it
Вопросы
-
Учитывая экземпляр AdaptiveIconDrawable, как вы его формируете, чтобы быть круглой формы, прямоугольника, закругленного прямоугольника, слезы и т.д.?
-
Как удалить фигуру и по-прежнему иметь допустимый размер значка (используя его передний план в нем)? Официальный размер значка приложения для пусковых установок - 48 дп, в то время как официальные для внутренних чертежей AdaptiveIconDrawable - 72dp (передний план), 108dp (фон). Я предполагаю, что это означало бы, что выкладывать передний план, изменить его каким-то образом и преобразовать в растровое изображение.
-
В каком случае полезно использовать
IconCompat.createWithAdaptiveBitmap()
? Было написано, что "Если вы создаете динамический ярлык с использованием растрового изображения, вы можете найти значок Support Library 26.0.0-beta2s IconCompat.createWithAdaptiveBitmap(), который полезен для обеспечения правильной маскировки вашего растрового изображения в соответствии с другими адаптивными значками"., но я не понимаю, в каких случаях это полезно.
EDIT: для создания растрового изображения из области переднего плана адаптивного значка, при изменении размера до нужного размера, я думаю, что это может быть хорошим решением:
val foregroundBitmap = convertDrawableToBitmap(drawable.foreground)
val targetSize = convertDpToPixels(this, ...).toInt()
val scaledBitmap = ThumbnailUtils.extractThumbnail(foregroundBitmap, targetSize, targetSize, ThumbnailUtils.OPTIONS_RECYCLE_INPUT)
fun convertDrawableToBitmap(drawable: Drawable?): Bitmap? {
if (drawable == null)
return null
if (drawable is BitmapDrawable) {
return drawable.bitmap
}
val bounds = drawable.bounds
val width = if (!bounds.isEmpty) bounds.width() else drawable.intrinsicWidth
val height = if (!bounds.isEmpty) bounds.height() else drawable.intrinsicHeight
val bitmap = Bitmap.createBitmap(if (width <= 0) 1 else width, if (height <= 0) 1 else height,
Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
drawable.setBounds(0, 0, canvas.width, canvas.height)
drawable.draw(canvas)
drawable.bounds = bounds;
return bitmap
}
fun convertDpToPixels(context: Context, dp: Float): Float = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.resources.displayMetrics)
Возможно, вы сможете избежать двух растровых изображений одновременно, но это нормально, я думаю.
О создании формы, выбирая различные типы, я все еще не уверен, как это сделать. Единственное решение, которое я видел в ответах ниже, - использовать округленный прямоугольник или круг, но есть другие формы (например, слеза), которые могут прийти на ум.