Сказано - сделано; делаем цифровые часы.Смысл этого туториала в том, чтобы показать, как использовать в виджете поменьше ресурсов и при этом нарисовать что-то симпатичное; к примеру тут цифры белые и красные - в каком-то из виджетов (очень похожем на этот по конструкции, минуты перекрывают часы) использовались отдельно картинки для белых цифр, отдельно для синих, собственно можно было использовать единственный вариант расцветки, тут я это "пофикшу"
Для начала надо надизайнить макет, в фотошопе/гимпе я беру скриншот с эмулятора, ограничиваю пространство для виджета (он будет 2*2 клетки) и рисую собственно вот ту картинку выше. Шрифт Gota 100 пунктов. Пусть это все, ничего лишнего я добавлять не буду - надо подготовить изображение, которое будет использоваться для вывода цифр
Я сделал так: в отдельный файл я впечатал в колонку цифры от 0 до 9, черного цвета; в свойствах слоя с текстом я добавил наружную обводку, красного цвета, 5 пикселей размером. Теперь я добавляю пустой слой, размещаю его выше слоя с текстом, выделяю оба слоя и нажимаю Ctrl-E - слои обьединяются и от текста не остается и следа - теперь это просто картинка; если все делать как я, то слой должен быть прозрачным, с черными буквами с красной обводкой, где-то посредине "листа.

По "замыслу" цифры должны быть "контурные", поэтому надо инструментом Magic Wand (Anti-Alias вкл, Tolerance 0) повыделять внутренности букв и поудалять выделенное - остануться только красные контуры, если все нормально

Почти готово, за исключением того, что расстояние между буквами неприлично неправильное, надо сместить все буквы друг к дружке и обрезать файл; я например сделал так - по самой большой букве (ну вообще этот шрифт моноширинный, но в общем случае) выделил габарит будущего символа, разметил место для 10 символов и поперетаскивал все цифры так, чтобы они помещались ровно в центре своих ячеек. Не знаю, понятна ли мысль и как это проиллюстировать, вот что-то такое должно получится в процессе:


Дальше надо начать новый проект, добавить в его ресурсы файл с цифрами, сделать заготовку виджета 2*2манифест и xml с описанием) и файл разметки, пусть он пока выглядит так:
Т.е. просто выводится картинка, все.
Ну и код для рисования (все упрощено до минимума, часы обновляться не будут, смысл - показать, как сделать картинку):
package com.example;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.*;
import android.widget.RemoteViews;
import java.util.Calendar;
public class DigiWidget extends AppWidgetProvider {
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Calendar curDateTime = Calendar.getInstance(); // это текущее время/дата
// вообще нам надо знать только часы и минуты сейчас..
final int hh = curDateTime.get(Calendar.HOUR);
final int mm = curDateTime.get(Calendar.MINUTE);
Bitmap bmp = null; // а вот это - будущий "циферблат"
Resources r = context.getResources(); // так мы будем пользоваться ресурсами
final Bitmap digits = BitmapFactory.decodeResource(r, R.drawable.test_digits);
final int w = digits.getWidth();
final int h = digits.getHeight() / 10;
// ^^ я загрузил подготовленную картинку с цифрами и узнал ее размер
// создаю битмап, по которому буду "рисовать"; чтобы не терять детали, надо использовать ARGB8888
// при его создании, "тру" 32-битный цвет
bmp = Bitmap.createBitmap(w * 2, h * 2, Bitmap.Config.ARGB_8888);
// а это - "холст"; по нему можно "мазюкать" кисточками/перьями/штампами etc
// все, что намазюкаю в меру своего художественного таланта отобразится в битмап
Canvas canvas = new Canvas(bmp);
// этот обьект используется для настройки рисования по холсту; например..
Paint p = new Paint();
// сейчас я скажу, что все что рисуется должно окрашиваться в белый цвет
// вот и наши белые буквы, для которых нет отдельных картинок ;)
p.setColorFilter(new PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP));
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
// тут я вывожу цифры для часов; координаты холста меняются снизу вверх слева направо
// так что у первой цифры (десятки часов) координата всегда (0, 0), у второй (единицы
// часов) - (w, 0), ц - это ширина каждой цифры
// drawBitmap рисует по холсту битмап, а точнее он вырезает из битмапа digits
// часть картинки, которая ограничивается прямоугольником, чьи размеры передаются 2-м параметром,
// и кладет этот вырезанный кусок на холст в прямоугольник, указанный в 3-м параметре
// при этом используются настройки, которые передаются в 4-м параметре (в этом случае
// все окрашивается в белый цвет)
int dh = hh / 10;
canvas.drawBitmap(digits, new Rect(0, dh * h, w, (dh + 1) * h), new Rect(0, 0, w, h), p);
dh = hh % 10;
canvas.drawBitmap(digits, new Rect(0, dh * h, w, (dh + 1) * h), new Rect(w, 0, 2 * w, h), p);
int dy = 60; // экспериментально/дизайнерски подобранная цифра -
// насколько минуты "перехлещиваются" с цифрами
// минуты я хочу вывести.. СИНИМ цветом, цифры лягут поверх часов (можно задавать и
// другие варианты наложения
p.setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.SRC_ATOP));
p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
dh = mm / 10;
canvas.drawBitmap(digits, new Rect(0, dh * h, w, (dh + 1) * h), new Rect(0, dy, w, dy + h), p);
dh = mm % 10;
canvas.drawBitmap(digits, new Rect(0, dh * h, w, (dh + 1) * h), new Rect(w, dy, 2 * w, dy + h), p);
digits.recycle(); // освобождаем битмап сразу же, чтобы не накапливать память -
// когда там его увидит/освободит сборщик мусора
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.test);
for (int appWidgetId : appWidgetIds) {
views.setImageViewBitmap(R.id.idTestImage, bmp);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Не без глюка (при "старте" виджета выводится на мгновение картинка левая, лень убирать из xml разметки ссылку на картинку), но получаем следующее (слева - работающий виджет):
Если ничего не накосячил - вот архив с проектом: скачать быстро и без рекламы :)
Не ходят часы(
ОтветитьУдалить