我有一个数字时钟小工具。我如何使用从资产/字体自定义字体作为TextView的默认字体显示时钟?
这是我的code:
包android.tristan.widget.digiclock;
进口的java.util.Calendar;
进口android.app.PendingIntent;
进口android.app.Service;
进口android.appwidget.AppWidgetManager;
进口android.appwidget.AppWidgetProvider;
进口android.content.BroadcastReceiver;
进口android.content.ComponentName;
进口android.content.Context;
进口android.content.Intent;
进口android.content.IntentFilter;
进口android.os.IBinder;
进口android.os.Vibrator;
进口android.text.format.DateFormat;
进口android.widget.RemoteViews;
公共类DigiClock扩展AppWidgetProvider {
@覆盖
公共无效onDisabled(上下文的背景下){
super.onDisabled(上下文);
context.stopService(新意图(背景下,UpdateService.class));
}
公共无效的onReceive(上下文的背景下,意图意图)
{
super.onReceive(背景下,意图);
如果(intent.getAction()。等于(android.tristan.widget.digiclock.CLICK))
{
振动器振动=(震动)context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(50);
最终意图alarmClockIntent =新的意图(Intent.ACTION_MAIN,NULL);
alarmClockIntent.addCategory(Intent.CATEGORY_LAUNCHER);
最终的组件名CN =新的组件名(com.android.deskclock,com.android.deskclock.AlarmClock);
alarmClockIntent.setComponent(CN);
alarmClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmClockIntent);
}
如果(intent.getAction()。等于(android.tristan.widget.digiclock.CLICK_2))
{
振动器振动=(震动)context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(50);
最终意图calendarIntent =新的意图(Intent.ACTION_MAIN,NULL);
calendarIntent.addCategory(Intent.CATEGORY_LAUNCHER);
最终的组件名CN =新的组件名(com.android.calendar,com.android.calendar.LaunchActivity);
calendarIntent.setComponent(CN);
calendarIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(calendarIntent);
}
}
@覆盖
公共无效onEnabled(上下文的背景下){
super.onEnabled(上下文);
context.startService(新意图(UpdateService.ACTION_UPDATE));
}
@覆盖
公共无效的OnUpdate(上下文的背景下,AppWidgetManager appWidgetManager,INT [] appWidgetIds){
super.onUpdate(背景下,appWidgetManager,appWidgetIds);
context.startService(新意图(UpdateService.ACTION_UPDATE));
最终诠释顶级= appWidgetIds.length;
最终诠释底= appWidgetIds.length;
的for(int i = 0; I<顶;我++)
{
INT [] appWidgetId = appWidgetIds;
RemoteViews顶部=新RemoteViews(context.getPackageName(),R.layout.main);
意图clickintent =新的意向书(android.tristan.widget.digiclock.CLICK);
PendingIntent pendingIntentClick = PendingIntent.getBroadcast(上下文,0,clickintent,0);
top.setOnClickPendingIntent(R.id.TopRow,pendingIntentClick);
appWidgetManager.updateAppWidget(appWidgetId,顶部);
}
的for(int i = 0; I<底部;我++)
{
INT [] appWidgetId = appWidgetIds;
RemoteViews底部=新RemoteViews(context.getPackageName(),R.layout.main);
意图clickintent =新的意向书(android.tristan.widget.digiclock.CLICK_2);
PendingIntent pendingIntentClick = PendingIntent.getBroadcast(上下文,0,clickintent,0);
bottom.setOnClickPendingIntent(R.id.BottomRow,pendingIntentClick);
appWidgetManager.updateAppWidget(appWidgetId,底部);
}
}
公共静态final类UpdateService延伸服务{
静态最后弦乐ACTION_UPDATE =android.tristan.widget.digiclock.action.UPDATE;
私人最终静态的IntentFilter sIntentFilter;
私人最终静态字符串FORMAT_12_HOURS =H:MM;
私人最终静态字符串FORMAT_24_HOURS =KK:MM;
私人字符串mTimeFormat;
私人字符串mDateFormat;
私人字符串mDayFormat;
私人日历mCalendar;
静态{
sIntentFilter =新的IntentFilter();
sIntentFilter.addAction(Intent.ACTION_TIME_TICK);
sIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
sIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
}
@覆盖
公共无效的onCreate(){
super.onCreate();
reinit的();
registerReceiver(mTimeChangedReceiver,sIntentFilter);
}
@覆盖
公共无效的onDestroy(){
super.onDestroy();
unregisterReceiver(mTimeChangedReceiver);
}
@覆盖
公共无效ONSTART(意向意图,诠释startId){
super.onStart(意向,startId);
如果(ACTION_UPDATE.equals(intent.getAction())){
更新();
}
}
@覆盖
公众的IBinder onBind(意向意图){
返回null;
}
私人无效更新(){
mCalendar.setTimeInMillis(System.currentTimeMillis的());
最后的CharSequence时间= DateFormat.format(mTimeFormat,mCalendar);
最后的CharSequence日期= DateFormat.format(mDateFormat,mCalendar);
最后的CharSequence天= DateFormat.format(mDayFormat,mCalendar);
RemoteViews意见=新RemoteViews(getPackageName(),R.layout.main);
views.setTextViewText(R.id.Time,时间);
views.setTextViewText(R.id.Day,日);
views.setTextViewText(R.id.Date,日期);
组件名小部件=新的组件名(本,DigiClock.class);
AppWidgetManager经理= AppWidgetManager.getInstance(本);
manager.updateAppWidget(窗口小部件,意见);
}
私人无效reinit的(){
mDayFormat =的getString(R.string.day_format);
mDateFormat =的getString(R.string.date_format);
mTimeFormat = is24HourMode(本)? FORMAT_24_HOURS:FORMAT_12_HOURS;
mCalendar = Calendar.getInstance();
}
私有静态布尔is24HourMode(最终上下文的背景下){
返回android.text.format.DateFormat.is24HourFormat(上下文);
}
私人最终的BroadcastReceiver mTimeChangedReceiver =新的BroadcastReceiver(){
@覆盖
公共无效的onReceive(上下文的背景下,意图意图){
最后弦乐行动= intent.getAction();
如果(action.equals(Intent.ACTION_TIME_CHANGED)||
action.equals(Intent.ACTION_TIMEZONE_CHANGED))
{
reinit的();
}
更新();
}
};
}
}
解决方案
我们需要的是渲染字体到画布上,然后将它传递给一个位图并将其赋值给一个ImageView的。像这样:
公共位图buildUpdate(字符串时)
{
位图MYBITMAP = Bitmap.createBitmap(160,84,Bitmap.Config.ARGB_4444);
帆布myCanvas =新的Canvas(MYBITMAP);
涂料粉刷=新的油漆();
字体时钟= Typeface.createFromAsset(this.getAssets(),Clockopia.ttf);
paint.setAntiAlias(真正的);
paint.setSubpixelText(真正的);
paint.setTypeface(时钟);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTextSize(65);
paint.setTextAlign(Align.CENTER);
myCanvas.drawText(时间,80%,60,油漆);
返回MYBITMAP;
}
这部分做的字体图像的thingie,这是如何使用它:
字符串时间=(字符串)DateFormat.format(mTimeFormat,mCalendar);
RemoteViews意见=新RemoteViews(getPackageName(),R.layout.main);
views.setImageViewBitmap(R.id.TimeView,buildUpdate(时间));
正如你可能会注意到,这code只是显示当前时间在ImageView的,但它可以很容易地调整到任何需要。
I have a digital clock widget. How can I use a custom font from assets/fonts as the default font in the textview showing the clock?
This is my code:
package android.tristan.widget.digiclock;
import java.util.Calendar;
import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.os.Vibrator;
import android.text.format.DateFormat;
import android.widget.RemoteViews;
public class DigiClock extends AppWidgetProvider {
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
context.stopService(new Intent(context, UpdateService.class));
}
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
if(intent.getAction().equals("android.tristan.widget.digiclock.CLICK"))
{
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(50);
final Intent alarmClockIntent = new Intent(Intent.ACTION_MAIN, null);
alarmClockIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.deskclock", "com.android.deskclock.AlarmClock");
alarmClockIntent.setComponent(cn);
alarmClockIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmClockIntent);
}
if(intent.getAction().equals("android.tristan.widget.digiclock.CLICK_2"))
{
Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(50);
final Intent calendarIntent = new Intent(Intent.ACTION_MAIN, null);
calendarIntent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.calendar", "com.android.calendar.LaunchActivity");
calendarIntent.setComponent(cn);
calendarIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(calendarIntent);
}
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
context.startService(new Intent(UpdateService.ACTION_UPDATE));
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
context.startService(new Intent(UpdateService.ACTION_UPDATE));
final int Top = appWidgetIds.length;
final int Bottom = appWidgetIds.length;
for (int i=0; i<Top; i++)
{
int[] appWidgetId = appWidgetIds;
RemoteViews top=new RemoteViews(context.getPackageName(), R.layout.main);
Intent clickintent=new Intent("android.tristan.widget.digiclock.CLICK");
PendingIntent pendingIntentClick=PendingIntent.getBroadcast(context, 0, clickintent, 0);
top.setOnClickPendingIntent(R.id.TopRow, pendingIntentClick);
appWidgetManager.updateAppWidget(appWidgetId, top);
}
for (int i=0; i<Bottom; i++)
{
int[] appWidgetId = appWidgetIds;
RemoteViews bottom=new RemoteViews(context.getPackageName(), R.layout.main);
Intent clickintent=new Intent("android.tristan.widget.digiclock.CLICK_2");
PendingIntent pendingIntentClick=PendingIntent.getBroadcast(context, 0, clickintent, 0);
bottom.setOnClickPendingIntent(R.id.BottomRow, pendingIntentClick);
appWidgetManager.updateAppWidget(appWidgetId, bottom);
}
}
public static final class UpdateService extends Service {
static final String ACTION_UPDATE = "android.tristan.widget.digiclock.action.UPDATE";
private final static IntentFilter sIntentFilter;
private final static String FORMAT_12_HOURS = "h:mm";
private final static String FORMAT_24_HOURS = "kk:mm";
private String mTimeFormat;
private String mDateFormat;
private String mDayFormat;
private Calendar mCalendar;
static {
sIntentFilter = new IntentFilter();
sIntentFilter.addAction(Intent.ACTION_TIME_TICK);
sIntentFilter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
sIntentFilter.addAction(Intent.ACTION_TIME_CHANGED);
}
@Override
public void onCreate() {
super.onCreate();
reinit();
registerReceiver(mTimeChangedReceiver, sIntentFilter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mTimeChangedReceiver);
}
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
if (ACTION_UPDATE.equals(intent.getAction())) {
update();
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
private void update() {
mCalendar.setTimeInMillis(System.currentTimeMillis());
final CharSequence time = DateFormat.format(mTimeFormat, mCalendar);
final CharSequence date = DateFormat.format(mDateFormat, mCalendar);
final CharSequence day = DateFormat.format(mDayFormat, mCalendar);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.main);
views.setTextViewText(R.id.Time, time);
views.setTextViewText(R.id.Day, day);
views.setTextViewText(R.id.Date, date);
ComponentName widget = new ComponentName(this, DigiClock.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(widget, views);
}
private void reinit() {
mDayFormat = getString(R.string.day_format);
mDateFormat = getString(R.string.date_format);
mTimeFormat = is24HourMode(this) ? FORMAT_24_HOURS : FORMAT_12_HOURS;
mCalendar = Calendar.getInstance();
}
private static boolean is24HourMode(final Context context) {
return android.text.format.DateFormat.is24HourFormat(context);
}
private final BroadcastReceiver mTimeChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(Intent.ACTION_TIME_CHANGED) ||
action.equals(Intent.ACTION_TIMEZONE_CHANGED))
{
reinit();
}
update();
}
};
}
}
解决方案
What is needed is to render the font onto a canvas, and then pass it on to a bitmap and assign that to an ImageView. Like so:
public Bitmap buildUpdate(String time)
{
Bitmap myBitmap = Bitmap.createBitmap(160, 84, Bitmap.Config.ARGB_4444);
Canvas myCanvas = new Canvas(myBitmap);
Paint paint = new Paint();
Typeface clock = Typeface.createFromAsset(this.getAssets(),"Clockopia.ttf");
paint.setAntiAlias(true);
paint.setSubpixelText(true);
paint.setTypeface(clock);
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setTextSize(65);
paint.setTextAlign(Align.CENTER);
myCanvas.drawText(time, 80, 60, paint);
return myBitmap;
}
That's the part doing the font to image thingie, and this is how to use it:
String time = (String) DateFormat.format(mTimeFormat, mCalendar);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.main);
views.setImageViewBitmap(R.id.TimeView, buildUpdate(time));
As you might notice, this code just shows the current time in the imageview, but it can easily be adjusted to whatever needs.