Frage

Ich habe eine digitale Uhr-Widget. Wie kann ich eine benutzerdefinierte Schriftart von Vermögenswerten / Schriften als die Standardschriftart in der Textview die Uhr zeigt?

Dies ist mein 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();
            }
        };
    }
}
War es hilfreich?

Lösung

Was benötigt wird, ist die Schrift auf eine Leinwand zu machen, und es dann weitergeben an eine Bitmap und weist das zu einem Image. Wie 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;
}

Das ist der Teil zu tun, die Schriftart zu Bild thingie, und das ist, wie es zu benutzen:

String time = (String) DateFormat.format(mTimeFormat, mCalendar);
RemoteViews views = new RemoteViews(getPackageName(), R.layout.main);
views.setImageViewBitmap(R.id.TimeView, buildUpdate(time));

Wie Sie vielleicht bemerkt, dieser Code nur zeigt die aktuelle Uhrzeit in der Imageview, aber es kann leicht zu, was Bedürfnisse angepasst werden.

Edit:

ist ARGB_4444 für ARGB_8888 veraltet wie in der Dokumentation angegeben

  

Dieses Feld in API-Ebene weiterentwickelt wurde 13. Wegen der schlechten Qualität dieser Konfiguration ist es ratsam, ARGB_8888 stattdessen zu verwenden.

Andere Tipps

änderte ich ein wenig über Maß Größe, so dass die Bitmap verschiedene Schriften unterstützt. Es nur einzeiligen Text unterstützen.

public static Bitmap getFontBitmap(Context context, String text, int color, float fontSizeSP) {
    int fontSizePX = convertDiptoPix(context, fontSizeSP);
    int pad = (fontSizePX / 9);
    Paint paint = new Paint();
    Typeface typeface = Typeface.createFromAsset(context.getAssets(), "Fonts/Roboto-Regular.ttf");
    paint.setAntiAlias(true);
    paint.setTypeface(typeface);
    paint.setColor(color);
    paint.setTextSize(fontSizePX);

    int textWidth = (int) (paint.measureText(text) + pad * 2);
    int height = (int) (fontSizePX / 0.75);
    Bitmap bitmap = Bitmap.createBitmap(textWidth, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    float xOriginal = pad;
    canvas.drawText(text, xOriginal, fontSizePX, paint);
    return bitmap;
}

public static int convertDiptoPix(Context context, float dip) {
    int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, context.getResources().getDisplayMetrics());
    return value;
}

Dies macht die Schriftart in eine Bitmap, und ordnet dann die Bitmap in einem Image.

public static RemoteViews buildUpdate(Context context)
{
    RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
    Bitmap myBitmap = Bitmap.createBitmap(100, 50, Bitmap.Config.ARGB_4444);
    Canvas myCanvas = new Canvas(myBitmap);
    Paint paint = new Paint();
    Typeface clock = Typeface.createFromAsset(context.getAssets(),"Clockopia.ttf");
    paint.setAntiAlias(true);
    paint.setSubpixelText(true);
    paint.setTypeface(clock);
    paint.setStyle(Paint.Style.FILL);
    paint.setColor(Color.BLACK);
    paint.setTextSize(15);
    myCanvas.drawText("Test", 0, 20, paint);

    views.setImageViewBitmap(R.id.TimeView, myBitmap);

    return views;
}

Diese Lösung wird eine Bitmap erstellen, die genaue Größe ist erforderlich, um den Text zu passen.

/**
 * Creates and returns a new bitmap containing the given text.
 */
public static Bitmap createTextBitmap(final String text, final Typeface typeface, final float textSizePixels, final int textColour)
{
    final TextPaint textPaint = new TextPaint();
    textPaint.setTypeface(typeface);
    textPaint.setTextSize(textSizePixels);
    textPaint.setAntiAlias(true);
    textPaint.setSubpixelText(true);
    textPaint.setColor(textColour);
    textPaint.setTextAlign(Paint.Align.LEFT);
    Bitmap myBitmap = Bitmap.createBitmap((int) textPaint.measureText(text), (int) textSizePixels, Bitmap.Config.ARGB_8888);
    Canvas myCanvas = new Canvas(myBitmap);
    myCanvas.drawText(text, 0, myBitmap.getHeight(), textPaint);
    return myBitmap;
}

Wie an anderer Stelle erwähnt, kann die Bitmap dann zu einem widget Image zugeordnet werden.

final Bitmap textBitmap = createTextBitmap(text,
        FontManager.get().getTypeface("slab-serif", 0),
        context.getResources().getDimension(R.dimen.widget_font_size_large),
        context.getResources().getColor(R.color.widget_text)
);
views.setImageViewBitmap(R.id.widget_cardTextImage, textBitmap);

Dies hat den Vorteil, dass ein Bitmap-Herstellung, die nie Über- oder Unterschreiten den Text soll es enthalten, die für Widgets wichtig ist, da ihre Abmessungen zwischen den Geräten und Versionen variieren.

Ich kann es jetzt nicht finden, aber ich die gleiche Frage gestellt und bekam eine Antwort von Google, dass dies nicht möglich ist. Sie sind wirklich eingeschränkt in dem, was Sie mit AppWidgets tun kann, zum Beispiel nur Sie bestimmte UI-Widgets verwenden können, und Sie können nicht benutzerdefinierte Schriftarten verwenden.

remoteviews.setTextViewText(textview_id, new SpannableStringBuilder(Html.fromHtml("<b>"+some_text_vaeiable"+"</b>")) );

Dies ist, wie ich es in meinen Anwendungen, sollte auch für Widgets gelten.

Typeface customfont = Typeface.createFromAsset(getAssets(), "fonts/somefont.ttf");
TextView textview = (TextView) findViewById(R.id.textview);
textview.setTypeface(customfont);
textview.setText("Hey custom font!"); 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top