Android字体学习

Android字体学习

1. sdk自带字体

<TextView
        android:id="@+id/tv_show_normal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="SDK自带字体:normal"
        android:textColor="#333333"
        android:textSize="25sp"
        android:typeface="normal" />

    <TextView
        android:id="@+id/tv_show_monospace"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="SDK自带字体:monospace"
        android:textColor="#333333"
        android:textSize="25sp"
        android:typeface="monospace" />

    <TextView
        android:id="@+id/tv_show_sans"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="SDK自带字体:sans"
        android:textColor="#333333"
        android:textSize="25sp"
        android:typeface="sans" />

    <TextView
        android:id="@+id/tv_show_serif"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="SDK自带字体:serif"
        android:textColor="#333333"
        android:textSize="25sp"
        android:typeface="serif" />

在这里插入图片描述
默认自带的字体就四种,如上图,左边是没有设置系统字体的效果,右边设置了系统字体,可以看出要跟随系统字体,必须设置normal和sans(应该是这样吧,其它手机没试过,我测试机是OPPO)。

      int style = Typeface.NORMAL;
        switch (v.getId()) {
            case R.id.tv_bold:
                style = Typeface.BOLD;
                break;
            case R.id.tv_italic:
                style = Typeface.ITALIC;
                break;
            case R.id.tv_italic_bold:
                style = Typeface.BOLD_ITALIC;
                break;
        }
        normal.setTypeface(Typeface.DEFAULT, style);
        monospace.setTypeface(Typeface.MONOSPACE, style);
        sans.setTypeface(Typeface.SANS_SERIF, style);
        serif.setTypeface(Typeface.SERIF, style);

代码设置可以如上进行设置。

2. 三方字体

<TextView
        android:id="@+id/tv_gtw"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/gtw"
        android:padding="10dp"
        android:text="三方字体:GNUTypewriter"
        android:textColor="#333333"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_oswald"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/oswald_stencbab"
        android:padding="10dp"
        android:text="三方字体:Oswald"
        android:textColor="#333333"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_roboto_bold"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/roboto_bold"
        android:padding="10dp"
        android:text="三方字体:Roboto(Bold)"
        android:textColor="#333333"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_roboto_condensed"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/roboto_condensed_regular"
        android:padding="10dp"
        android:text="三方字体:Roboto Condensed"
        android:textColor="#333333"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_roboto_thin_italic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/roboto_thin_italic"
        android:padding="10dp"
        android:text="三方字体:Roboto-ThinItalic"
        android:textColor="#333333"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/tv_roboto_thin_italic_compare"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fontFamily="@font/roboto_thin_italic"
        android:padding="10dp"
        android:text="三方字体:Roboto-ThinItalic. fontFamily有比typeface更高的优先级"
        android:textColor="#333333"
        android:textSize="25sp"
        android:typeface="normal" />

在这里插入图片描述
在这里插入图片描述
以上四图分别对应textStyle的normal;bold;italic;italic|bold. 可以看出部分字体并不买textStyle的账(应该是字体资源文件本身的支持问题),所以三方字体的使用要注意能不能满足需求。

3. 三方字体动态加载

    public void getFromResource() {
        res.setTypeface(ResourcesCompat.getFont(activity, R.font.roboto_bold));
    }

    public void getFromAssets() {
        assets.setTypeface(Typeface.createFromAsset(activity.getAssets(), "roboto_thin_italic.ttf"));
    }

    public void getFromFile() {
        new Thread() {
            @Override
            public void run() {
                File f = null;
                try {
                    InputStream is = activity.getAssets().open("gtw.ttf");
                    f = new File(activity.getExternalCacheDir(), "font" + File.separator + "gtw.ttf");
                    if (!f.exists()) {
                        if (f.getParentFile().exists() || f.getParentFile().mkdirs()) {
                            FileOutputStream fos = new FileOutputStream(f);
                            byte[] b = new byte[1024 * 8];
                            int readLen = -1;
                            while ((readLen = is.read(b)) > 0) {
                                fos.write(b, 0, readLen);
                            }
                        }
                    }
                } catch (IOException ignore) {
                }
                Typeface typeface = null;
                try {
                    typeface = Typeface.createFromFile(f);
                } catch (Exception e) {
                    if (f != null) {
                        f.delete();
                    }
                }
                final Typeface forUse = typeface;
                file.post(new Runnable() {
                    @Override
                    public void run() {
                        if (forUse == null) {
                            return;
                        }
                        file.setTypeface(forUse);
                    }
                });
            }
        }.start();
    }

三方字体可以直接配在res/font目录下,也可以丢在assets或者直接从网上下载到某个目录下,加载方式如上代码。

    private void updateTextStyle() {
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
            return;
        }
        Typeface.Builder builder = new Typeface.Builder(activity.getAssets(), "roboto_condensed_regular.ttf");
        // 不咋好使
//        FontVariationAxis wght = new FontVariationAxis("wght", 900);
//        FontVariationAxis ital = new FontVariationAxis("ital", 1f);
//
//        builder.setFontVariationSettings(new FontVariationAxis[] {wght, ital});
        // 字体资源文件是字体集合时指定其中一个,如果不是可以不调用,调用0也行
        builder.setTtcIndex(0);

        builder.setItalic(true);
        builder.setWeight(500);
        text.setTypeface(builder.build());
    }

也可以通过Typeface.Builder来配置字体粗细(wght,0-1000,100梯度)和倾斜(ital,1和其它值)。

这玩意sdk版本要求太高基本上价值不大,目前仅支持wght和ital,wdth、slnt和opsz并不支持(可以查看FontFileUtil.analyzeStyle的源码来确认这点)这五个字段是啥可以看这里

setTtcIndex针对三方字体文件是字体组的情况,index是几就指向字体组的第几个字体,超过字体组的数量也没啥问题,会使用系统默认字体(没找到这种资源,感觉没啥用)

setItalic是否倾斜,setWeight字体粗细设置,通过setFontVariationSettings设置有点不靠谱,粗细可以,倾斜不知道为啥不起作用。还有这个东西似乎有缓存不能动态变更粗细和倾斜(感觉更没用了)。

4. spannable支持

    private CharSequence getTargetText() {
        String meetingName = getString(R.string.meeting_name);
        String area = getString(R.string.area);
        String room = getString(R.string.room);
        String completeText = String.format(Locale.getDefault(), getString(R.string.test_long_text), meetingName, area, room);

        SpannableString res = new SpannableString(completeText);
        changeTextStyle(res, completeText, meetingName, R.font.gtw, Typeface.BOLD);
        changeTextStyle(res, completeText, area, R.font.oswald_stencbab, Typeface.ITALIC);
        changeTextStyle(res, completeText, room, R.font.roboto_condensed_regular, Typeface.BOLD_ITALIC);
        return res;
    }

    private void changeTextStyle(SpannableString res, String completeText, String text, int tf, int style) {
        int start = completeText.indexOf(text);
        int end = start + text.length();
        if (start >= end) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            res.setSpan(new TypefaceSpan(getTypeface(tf)), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
        } else {
            // 仅支持系统字体
            res.setSpan(new TypefaceSpan("serif"), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
        }
        res.setSpan(new StyleSpan(style), start, end, SpannableString.SPAN_EXCLUSIVE_EXCLUSIVE);
    }

看上面代码就知道支持得不好,三方字体必须Android28以上,以下只能改系统字体(那四个字体基本上没啥区别),反正就很无奈,溜了溜了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值