Android 字體medium實現

今天和視覺調樣式的時候,發現一個問題,我們代碼中經常使用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);

轉自:https://blog.csdn.net/rzleilei/article/details/110636893

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章