Android:创建一个可绘制对象,以不同的字体和大小显示两行文本,一行在另一行之上



我想创建一个显示两行文本的可绘制对象,一行在另一行之上。每行文本都必须采用自己的字体和文本大小,并且必须创建一个可绘制对象,因为我想将其设置为浮动操作按钮的可绘制对象。

private void updateFloatingButtonText(String headlineText, String subHeadlineText, FloatingActionButton floatingActionButton) {
    int headlineTextSize = getResources().getDimensionPixelSize(R.dimen.headlineTextSize);
    int subheadlineTextSize = getResources().getDimensionPixelSize(R.dimen.subheadlineTextSize);
    Spannable spannableStringHeadline = new SpannableString(headlineText);
    Spannable spannableStringSubheadline = new SpannableString(subHeadlineText);
    CustomTypefaceSpan boldSpan = new CustomTypefaceSpan("FontOne", FontCache.get("FontOne.ttf", this));
    CustomTypefaceSpan regularSpan = new CustomTypefaceSpan("FontTwo", FontCache.get("FontTwo.ttf", this));
    // set typeface headline
    spannableStringHeadline.setSpan(regularSpan, 0,
            headlineText.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE
    );

    // set typeface subtitle
    spannableStringSubheadline.setSpan(boldSpan, 0,
            subHeadlineText.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE
    );
       // set text size headline
    spannableStringHeadline.setSpan(new AbsoluteSizeSpan(headlineTextSize), 0,
            headlineText.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE
    );
     // set text size subline
    spannableStringSubheadline.setSpan(new AbsoluteSizeSpan(subheadlineTextSize), 0,
            subHeadlineText.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE
    );
    String finalString = TextUtils.concat(spannableStringHeadline, "n", spannableStringSubheadline);
    floatingActionButton.setImageDrawable([put the resulting drawable here]);
}

我已经编写了此方法,该方法可以创建完全按照我需要的方式格式化的单个字符串,但我仍然遇到从中创建可绘制对象的问题。

我尝试使用这个第三方库,但是尽管它以正确的字体显示文本,但它不会更改文本行的文本大小。

https://github.com/devunwired/textdrawable

有没有一种微不足道(或非平凡)的方法可以做到这一点?

通过创建一个如下所示的新类来解决:

public class TextToDrawable extends Drawable {
    private String headlineText = "";
    private String subHeadlineText = "";
    private final TextPaint headlinePaint = new TextPaint();
    private final TextPaint subHeadlinePaint = new TextPaint();
    public TextToDrawable(Context context, String headlineText, String subHeadlineText) {
        this.headlineText = headlineText;
        headlinePaint.setAntiAlias(true);
        headlinePaint.setTypeface(FontCache.get("FontA.ttf", context));
        headlinePaint.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.headlineTextSize));
        headlinePaint.setColor(ContextCompat.getColor(context, android.R.color.white));
        headlinePaint.setStyle(Paint.Style.FILL);
        headlinePaint.setTextAlign(Paint.Align.LEFT);
        this.subHeadlineText = subHeadlineText;
        subHeadlinePaint.setAntiAlias(true);
        subHeadlinePaint.setTypeface(FontCache.get("FontB.ttf", context));
        subHeadlinePaint.setTextSize(context.getResources().getDimensionPixelSize(R.dimen.subheadlineTextSize));
        subHeadlinePaint.setColor(ContextCompat.getColor(context, android.R.color.white));
        subHeadlinePaint.setStyle(Paint.Style.FILL);
        subHeadlinePaint.setTextAlign(Paint.Align.LEFT);
    }
    @Override
    public void draw(Canvas canvas) {
        Rect headlineWidth = new Rect();
        Rect subheadlineWidth = new Rect();
        headlinePaint.getTextBounds(headlineText, 0, headlineText.length(), headlineWidth);
        subHeadlinePaint.getTextBounds(subHeadlineText, 0, subHeadlineText.length(), subheadlineWidth);
        Rect bounds = new Rect();
        headlinePaint.getTextBounds(headlineText, 0, headlineText.length(), bounds);
        int x = getBounds().width() / 2 - (headlineWidth.width()/2);
        int y = (getBounds().height() / 2);
        canvas.drawText(headlineText, x, y, headlinePaint);
        x = getBounds().width()/2 - (subheadlineWidth.width()/2);
        y += headlinePaint.getFontSpacing();
        canvas.drawText(subHeadlineText, x, y, subHeadlinePaint);
    }
    @Override
    public void setAlpha(int alpha) {
    }
    @Override
    public void setColorFilter(ColorFilter colorFilter) {
    }
    @Override
    public int getOpacity() {
        return 0;
    }
}

然后像这样使用新类:

mFloatingActionButton.setImageDrawable(new TextToDrawable(this, "Headline", "Subheadline"));

这不是一个很好的解决方案,因为它只支持两行文本 - 这里没有任何动态内容。但是,我认为重写以支持更多行和更多字体会相当容易,并且它解决了当前的问题。

最新更新