You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中TextView字体样式无法修改问题求助

解决Android App Widget中TextView字体不生效的问题

你的问题核心在于:这是一个App Widget应用,而App Widget的布局由RemoteViews负责渲染,它对View属性的支持有严格限制——直接在XML中设置android:fontFamily(无论是自定义字体还是部分系统字体)都无法生效,因为RemoteViews不支持这种常规设置方式。

以下是针对不同API版本的可行解决方案:

方法1:API 26及以上版本(Android 8.0+)

从API 26开始,RemoteViews新增了setTextViewFontFamily方法,可以直接为TextView设置字体。修改你的updateClock方法:

import android.os.Build;

// ...

private void updateClock() {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, SexyClockWidget.class));

    for (int appWidgetId : appWidgetIds) {
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.sexy_clock_widget);

        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        String currentTime = sdf.format(new Date());
        views.setTextViewText(R.id.textView, currentTime);

        // 添加字体设置代码
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // 设置自定义字体(对应res/font/pixel.xml或res/font/pixel.ttf)
            views.setTextViewFontFamily(R.id.textView, "@font/pixel");
            // 如果要设置系统字体,直接传字体名称即可,例如:
            // views.setTextViewFontFamily(R.id.textView, "monospace");
        }

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

方法2:兼容API 26以下版本

对于低版本系统,需要通过SpannableString结合自定义TypefaceSpan来加载字体:

步骤1:创建自定义TypefaceSpan类

import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;

public class CustomTypefaceSpan extends TypefaceSpan {
    private final Typeface mTypeface;

    public CustomTypefaceSpan(String family, Typeface typeface) {
        super(family);
        mTypeface = typeface;
    }

    @Override
    public void updateDrawState(TextPaint ds) {
        applyCustomTypeface(ds, mTypeface);
    }

    @Override
    public void updateMeasureState(TextPaint paint) {
        applyCustomTypeface(paint, mTypeface);
    }

    private static void applyCustomTypeface(Paint paint, Typeface tf) {
        int oldStyle;
        Typeface old = paint.getTypeface();
        oldStyle = old == null ? 0 : old.getStyle();

        int fake = oldStyle & ~tf.getStyle();
        if ((fake & Typeface.BOLD) != 0) {
            paint.setFakeBoldText(true);
        }

        if ((fake & Typeface.ITALIC) != 0) {
            paint.setTextSkewX(-0.25f);
        }

        paint.setTypeface(tf);
    }
}

步骤2:在updateClock中使用SpannableString设置字体

private void updateClock() {
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
    int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, SexyClockWidget.class));

    // 加载自定义字体(字体文件放在src/main/assets/font/目录下,例如pixel.ttf)
    Typeface pixelTypeface = Typeface.createFromAsset(context.getAssets(), "font/pixel.ttf");

    for (int appWidgetId : appWidgetIds) {
        RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.sexy_clock_widget);

        SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
        String currentTime = sdf.format(new Date());

        // 用SpannableString包裹文本并设置字体
        SpannableString spannableText = new SpannableString(currentTime);
        spannableText.setSpan(new CustomTypefaceSpan("", pixelTypeface), 0, currentTime.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        
        views.setTextViewText(R.id.textView, spannableText);

        appWidgetManager.updateAppWidget(appWidgetId, views);
    }
}

额外检查项

  • 确保自定义字体文件路径正确:API 26+使用res/font/目录,低版本使用src/main/assets/font/目录,文件名无拼写错误。
  • 系统字体尽量选择RemoteViews明确支持的基础字体(如sans-serif、serif、monospace),避免使用小众或新增的系统字体变体。

内容的提问来源于stack exchange,提问作者mike9999

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:55:07