今天和视觉调样式的时候,发现一个问题,我们代码中经常使用fontFamily的样式,比如:

  <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="@dimen/dip12"
            android:text="小粗体样式"
            android:textColor="@color/color_333333"
            android:textSize="@dimen/dip12"
            android:fontFamily="sans-serif-medium" />
//设置sans-serif-medium样式

但是如果我不是通过xml设置样式,而是想在自定义View中设置这种样式该怎么做呢?百度了一下,竟然没有找到相关的文章,真想给差评啊!那就只能靠自己了。

 

一/查看fontFamily属性的定义

该属性定义在系统的attrs.xml中,既然定义了一种属性,那么代码中一定会获取这个属性值。

 <!-- Default font family. -->
    <attr name="fontFamily" format="string" />

 

二/查看TextView源代码中如何使用的

首先获取属性值赋值给一个内部类TextAppearanceAttributes,该类专门存储相关属性值。赋值给了mFontFamily

 case com.android.internal.R.styleable.TextAppearance_fontFamily:
                    if (!context.isRestricted() && context.canLoadUnsafeResources()) {
                        try {
                            attributes.mFontTypeface = appearance.getFont(attr);
                        } catch (UnsupportedOperationException | Resources.NotFoundException e) {
                            // Expected if it is not a font resource.
                        }
                    }
                    if (attributes.mFontTypeface == null) {
                        attributes.mFontFamily = appearance.getString(attr);
                    }
                    attributes.mFontFamilyExplicit = true;
                    break;

然后看看哪里使用到mFontFamily。

//代码使用处  
 setTypefaceFromAttrs(attributes.mFontTypeface, attributes.mFontFamily,
                attributes.mTypefaceIndex, attributes.mStyleIndex, attributes.mFontWeight);


相关的方法
/**
     * Sets the Typeface taking into account the given attributes.
     *
     * @param typeface a typeface
     * @param familyName family name string, e.g. "serif"
     * @param typefaceIndex an index of the typeface enum, e.g. SANS, SERIF.
     * @param style a typeface style
     * @param weight a weight value for the Typeface or -1 if not specified.
     */
    private void setTypefaceFromAttrs(@Nullable Typeface typeface, @Nullable String familyName,
            @XMLTypefaceAttr int typefaceIndex, @Typeface.Style int style,
            @IntRange(from = -1, to = Typeface.MAX_WEIGHT) int weight) {
        if (typeface == null && familyName != null) {
            // Lookup normal Typeface from system font map.
            final Typeface normalTypeface = Typeface.create(familyName, Typeface.NORMAL);
            resolveStyleAndSetTypeface(normalTypeface, style, weight);
        } else if (typeface != null) {
            resolveStyleAndSetTypeface(typeface, style, weight);
        } else {  // both typeface and familyName is null.
            switch (typefaceIndex) {
                case SANS:
                    resolveStyleAndSetTypeface(Typeface.SANS_SERIF, style, weight);
                    break;
                case SERIF:
                    resolveStyleAndSetTypeface(Typeface.SERIF, style, weight);
                    break;
                case MONOSPACE:
                    resolveStyleAndSetTypeface(Typeface.MONOSPACE, style, weight);
                    break;
                case DEFAULT_TYPEFACE:
                default:
                    resolveStyleAndSetTypeface(null, style, weight);
                    break;
            }
        }
    }

所以参考源代码,我们就知道怎么使用了。

如果是TextView的话:

TextView textView=findViewById(R.id.text);
String familyName = "sans-serif-medium";
final Typeface normalTypeface = Typeface.create(familyName, Typeface.NORMAL);
textView.setTypeface(normalTypeface)

如果是TextPaint的话:

Paint paint = new Paint();
Typeface normalTypeface = Typeface.create("sans-serif-medium", Typeface.NORMAL);
paint.setTypeface(normalTypeface);

真的很简单,几分钟搞定,比百度中搜答案还快。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐