2012-03-25 104 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