Pull to refresh

Widgets. Custom fonts

Reading time 3 min
Views 10K
Столкнулся с ситуацией, когда было необходимо в виджете, на экране андофона, отобразить текст красивым нестандартным шрифтом. С того момента и начался сей пост.

Разработка виджета немного отличается от разработки activity, и вот это «немного» иногда ставит палки в колеса. Подробно расписывать разработку виджета я не буду, на Хабре уже есть несколько замечательных постов на эту тему (например, Hello World widget для Android или вообще такая вот шпаргалка, Создание Виджета), остановлюсь лишь на особенностях.

Суть проблемы

Проблема заключалась в том, что писать кастомным шрифтом в activity мы можем, установив всего лишь свойство Typeface необходимому нам View.

	Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/Aliner.ttf");
	TextView tv = (TextView) findViewById(R.id.txtFont);
	tv.setTypeface(tf);
	

А вот с виджетом такое уже не пройдет. Добраться до View мы можем только через объект RemoteViews, который предоставляет нам не очень то и большие возможности. До свойст «вьюшек» мы тоже так просто не доберемся, хотя значения некоторых, мы всё таки можем изменить через методы:
	remoteView.setInt(R.id.widgetPNG, "setAlpha", 50);
	remoteView.setBoolean(R.id.a_text_view, "setSelected", true);
	remoteView.setCharSequence(viewId, "setText", "Hello World!");
	.....
	

но вопрос со шрифтом остается открытым.

Решение было найдено с помощью Bitmap'ов.

Подключение кастомного шрифта

Первое что необходимо, это найти подходящий нам шрифт и покласть его в директорию ./assets/fonts/:


Далее остается только подключить его в коде виджета:
	Typeface tf = Typeface.createFromAsset(context.getAssets(),"fonts/Benegraphic.ttf");
	

Конверт текста в картинку

Как я уже говорил, работать мы будем с Bitmap'ом. Имея текст, преобразовать его в картинку нам поможет следующий метод:
	private Bitmap convertToImg(String text, Context context) 
	{
	    Bitmap btmText = Bitmap.createBitmap(400, 100, Bitmap.Config.ARGB_4444);
	    Canvas cnvText = new Canvas(btmText);
	    
	    Typeface tf = Typeface.createFromAsset(context.getAssets(),"fonts/Benegraphic.ttf");
	    
	    Paint paint = new Paint();
	    paint.setAntiAlias(true);
	    paint.setSubpixelText(true);
	    paint.setTypeface(tf);
	    paint.setColor(Color.WHITE);
	    paint.setTextSize(50);
	    
	    cnvText.drawText(text, 150, 50, paint);
	    return btmText;
	}
	

Метод convertToImg() возвращает уже готовый «битмап» с текстом, написанный шрифтом Benegraphic.ttf. Нам же остается только установить его в виджете.

Добавление «текста» в виджет

Установить сгенерированный bitmap в виджет труда особого не составит, это всего-то 3 строки кода:
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
	{
	    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
	    remoteViews.setImageViewBitmap(R.id.imText, convertToImg("Hello World!", context));
	    appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
	}
	

На этом весь кодинг заканчивается. Запустив приложение и установив виджет на один из рабочих столов мы увидим подобную картину:


Вот мы и получили кастомный шрифт в виджетах Android.

Заключение

Одним из способов, мы всё таки решили проблему. Это конечно был выход, но хотелось чего-то более нативного. Очень надеюсь что есть еще способы, но увы ни придумать, ни найти больше ничего другого не получилось. Люди в интернетах также задаются этим вопросом, но ответа пока не видел. Может быть кто-то из вас уже сталкивался, интересно было бы услышать в комментариях :)

Скачать весь проект можно здесь.
Tags:
Hubs:
+20
Comments 15
Comments Comments 15

Articles