2012-03-25 136 views
3

我正在尝试创建一个显示时间但使用自定义字体的简单Android小部件。任何人都知道如何做到这一点?我试过这个: Problem showing time using custom font小部件中的自定义字体

但它不起作用。首先getAssets()将不起作用,因为它需要上下文,并且如果我在几秒钟后删除设置自定义字体的行,我将得到失败的绑定事务错误。

任何人都可以帮助或给我一个教程的链接? 用定时器更新时间也是一个好习惯吗?

我的代码 LWidget.java

public class LWidget extends AppWidgetProvider { 

//============================================================================================= 
//On Update 
//============================================================================================= 


    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, 
    int[] appWidgetIds) { 
     Timer timer = new Timer(); 
     timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1, 1000); 



     //views.setImageViewBitmap(R.id.TimeView, buildUpdate(time)); 





    } 
//============================================================================================= 
//Timer class 
//============================================================================================= 

    private class MyTime extends TimerTask { 
     RemoteViews remoteViews; 
     AppWidgetManager appWidgetManager; 
     ComponentName thisWidget; 
     DateFormat timeformat = new SimpleDateFormat("kk:mm"); 
     public MyTime(Context context, AppWidgetManager appWidgetManager) { 
     this.appWidgetManager = appWidgetManager; 
     remoteViews = new RemoteViews(context.getPackageName(), R.layout.main); 
     thisWidget = new ComponentName(context, LWidget.class); 
    } 

    @Override 
    public void run() { 
     Calendar ci = Calendar.getInstance(); 
     String time = timeformat.format(ci.getTime()); 
     remoteViews.setTextViewText(R.id.widget_textview,"Time = " + time); 
     remoteViews.setImageViewBitmap(R.id.widget_imageview, buildUpdate(time)); 
     appWidgetManager.updateAppWidget(thisWidget, remoteViews); 
     } 
    } 

//============================================================================================= 
//bitmap font 
//============================================================================================= 
    public Bitmap buildUpdate(String time) 
{ 
     Bitmap myBitmap = Bitmap.createBitmap(160, 84, Bitmap.Config.ARGB_4444); 
     Canvas myCanvas = new Canvas(myBitmap); 
     Paint paint = new Paint(); 

     //if I remove the comment here, getAssets() will not work 

     //Typeface clock = Typeface.createFromAsset(this.getAssets(),"fonts/Crysta.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; 
} 




//============================================================================================= 
//On receive 
//============================================================================================= 
@Override 
    public void onReceive(Context context, Intent intent) { 
      // v1.5 fix that doesn't call onDelete Action 
      final String action = intent.getAction(); 
      if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) { 
      final int appWidgetId = intent.getExtras().getInt(
      AppWidgetManager.EXTRA_APPWIDGET_ID, 
      AppWidgetManager.INVALID_APPWIDGET_ID); 
      if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID) { 
       this.onDeleted(context, new int[] { appWidgetId }); 
      } 
      } else { 
       super.onReceive(context, intent); 
      } 
    } 

} 

main.xml中

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="fill_parent" 
android:orientation="vertical" 
android:layout_gravity="center" 
android:layout_height="wrap_content"> 

<TextView android:id="@+id/widget_textview" 
android:text="@string/widget_text" 
android:layout_height="wrap_content" 
android:layout_width="wrap_content" 
android:layout_gravity="center_horizontal|center" 
android:layout_marginTop="5dip" 
android:padding="10dip" 
android:textColor="@android:color/black"/> 

<ImageView 
    android:id="@+id/widget_imageview" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    /> 

</LinearLayout> 

ltime_widget_provider.xml

<?xml version="1.0" encoding="utf-8"?> 
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
android:minWidth="146dip" 
android:minHeight="72dip" 
android:updatePeriodMillis="10000" 
android:initialLayout="@layout/main" 
/> 
+0

Vincenzo尝试使用'getApplicationContext()'和'getBaseContext()'代替这个。 – 2012-03-25 16:02:19

回答

2

您必须使用AlarmManager而不是定时器。 您不能使用定时器because

AppWidgetProviderBroadcastReceiver的扩展,您 过程不能保证保持回调方法 返回后运行。

使用代码here作为参考。

getAssets()不会工作,因为它需要上下文

onUpdate()提供Context,不是吗?

0

好吧试试这个方法:

static Context con;

Typeface clock = Typeface.createFromAsset(con.getAssets(),“fonts/KacstLetter.ttf”);

+0

您的代码缺少'con'的赋值。只需进行这些更改,将导致NPE。除此之外,不需要将上下文保存在静态字段中,实际上这是一个坏主意,因为代码不能在不同的上下文中重用。只是去寻找一个常规的,非静态的领域。 PS:欢迎来到StackOverflow! – hiergiltdiestfu 2015-04-08 07:36:31

+0

对不起,我的意思是“静态上下文con;”把它放在 > public bitmap buildUpdate(String time){// ...} – 2015-04-08 08:36:46