Android字体SP与DP的区别

950 阅读3分钟

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

前提

我们有一个应用,该应用做了字体限制,当修改手机系统字体时,应用内的字体大小不随手机系统字体的改变而改变, 但是当测试小姐姐找着我给我演示之后有点蒙,看图说话

18406403-7aa8d4c71a24117d.png

上图可以看出,当季新品及标题处很明显有问题 因为我这一块是通过TextPaint画笔绘制的该TextView,所以一开始的考虑是不是画笔的问题,找了半天也找到原因,直到被别人提醒了一下,"你的textSize有没有通过sp和px进行转换"?然后感觉查看了代码

/**
 * @fileName RoundedTextSpanUtil
 * @data on  下午4:39
 * @author Kevin
 * @describe TODO
 * @org https://www.jianshu.com/u/ed346078c1d3
 * @email wangk8181@gmail.com
 **/
object RoundedTextSpanUtil {

    /**
     * 用在显示标题的时候在标题的开头加上标签
     *
     * @param context        上下文
     * @param textView       需要显示的view
     * @param cell           提示文字 标签
     * @param desc           标题
     * @param tipTextSize    标签的大小 (一般这个标签的大小要小于title的大小)
     * @param resultTextSize 标题的文字大小
     * @param radius         圆角半径
     */
    fun span(context: Context, textView: TextView, cell: String?, desc: String?, cellTextSize: Float, descTextSize: Float, radius: Float, background: Int, textColor: Int) {
        span(context, textView, cell, desc,null, cellTextSize, descTextSize, radius, background, textColor)
    }
    /**
     * 用在显示标题的时候在标题的开头加上标签
     *
     * @param context        上下文
     * @param textView       需要显示的view
     * @param cell           提示文字 标签
     * @param desc           标题
     * @param brand          需要加粗的文字(例如品牌名称)
     * @param tipTextSize    标签的大小 (一般这个标签的大小要小于title的大小)
     * @param resultTextSize 标题的文字大小
     * @param radius         圆角半径
     */
    fun span(context: Context, textView: TextView, cell: String?, desc: String?, brand: String?, cellTextSize: Float, descTextSize: Float, radius: Float, background: Int, textColor: Int) {
        smartLog {
            "brandEnName---$brand---desc---$desc---brandLength---${brand?.length}"
        }

        /**
         * 品牌的长度 + 标签(中古二手)长度 + 空格(1)
         */
        val endSpan: Int? = cell?.length?.let { brand?.length?.plus(it) }.let {
            it?.plus(1)
        }

        val builder = SpannableStringBuilder("$cell $desc")
        brand?.length?.let {
            if (endSpan != null) {
                builder.setSpan(StyleSpan(Typeface.BOLD), 0, endSpan, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
            }
        }
        //构造文字背景圆角
        //构造文字背景圆角
        val span = TextTagSpan(context, dip2px(48f), dip2px(14f)).let {
            it.setTextColor(textColor)
            it.setBackground(background)
            it.setRadius(dip2px(radius).toFloat())
            it.setTextSize(sp2px(cellTextSize).toFloat())
            it
        }

        cell?.length?.let { builder.setSpan(span, 0, it, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) }
        //构造标签文字大小
        //构造标签文字大小
        val spanSize = AbsoluteSizeSpan(sp2px(cellTextSize))
        cell?.length?.let { builder.setSpan(spanSize, 0, it, Spannable.SPAN_INCLUSIVE_INCLUSIVE) }
        //构造title文字大小
        //构造title文字大小
        val spanSizeLast = AbsoluteSizeSpan(sp2px(descTextSize))
        cell?.length?.let { builder.setSpan(spanSizeLast, it, builder.length, Spannable.SPAN_INCLUSIVE_INCLUSIVE) }

        textView.text = SpannableStringBuilder().let {
            it.append(builder)
        }
    }

    /**
     * 富文本字体部分加粗
     */
    fun spanStyle(title: String?, styleString: String?, textView: TextView) {

        val builder = SpannableStringBuilder(title)
        styleString?.length?.let {
            builder.setSpan(StyleSpan(Typeface.BOLD), 0, it, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)
        }
        textView.text = SpannableStringBuilder().let {
            it.append(builder)
        }
    }


}

得,我还真有通过sp2px(cellTextSize).toFloat()进行了字体的转换 然后尝试着用dp2px替换了sp2px之后果然没问题了

由此我们得到一个结论

  • 使用sp作为字体大小单位,会随着系统的字体大小改变
  • 而dp作为单位则不会.
关于sp,文档的描述为:

Scale-independent Pixels – This is like the dp unit, but it is also scaled by the user’s font size preference. It is recommend you use this unit when specifying font sizes, so they will be adjusted for both the screen density and the user’s preference.

大致意思为
  • sp除了受屏幕密度影响外,还受到用户的字体大小影响
  • 通常情况下,建议使用sp来跟随用户字体大小设置

因此通常情况下,我们还是建议使用sp作为字体的单位,除非一些特殊的情况,不想跟随系统字体变化的,可以使用dp.

参考文章 droidyue.com/blog/2016/0…