小部件中的自定义字体

3
我正在尝试创建一个简单的Android小部件,显示时间但使用自定义字体。有人知道如何做到这一点吗? 我已经尝试过这个: Problem showing time using custom font 但它不起作用。首先getAssets()将无法工作,因为它需要上下文,如果我删除设置自定义字体的行,几秒钟后我会得到失败的binder事务错误。 有人可以帮忙或给我一个教程链接吗? 另外,使用计时器更新时间是一个好的实践吗?
我的代码 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"
/>

Vincenzo尝试使用getApplicationContext()ĺ’ŚgetBaseContext()来代替这个。 - ρяσѕρєя K
2个回答

2
您必须使用 AlarmManager 而不是 Timer。您不能使用 Timer,因为

AppWidgetProviderBroadcastReceiver 的扩展,回调方法返回后进程无法保证持续运行。

请参考 此处的代码

getAssets() 将无法工作,因为它需要 Context。

onUpdate() 提供了一个 Context,对吧?

0

好的,尝试这种方式:

static Context con;  

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

您的代码缺少对con的赋值。仅进行这些更改将导致NPE。除此之外,没有必要将上下文保存为静态字段,事实上这是个坏主意,因为代码不能在不同的上下文中重用。最好使用常规的非静态字段。PS:欢迎来到StackOverflow! - hiergiltdiestfu
抱歉,我的意思是在以下代码之前添加 " static Context con; "
public Bitmap buildUpdate(String time) {// ... }
- Randa Harb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接