安卓中设置渐变字体和描边字体

打印 上一主题 下一主题

主题 1015|帖子 1015|积分 3045

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1.CommonFontSpan
  1. abstract class CommonFontSpan : ReplacementSpan() {
  2.     /** 测量的文本宽度  */
  3.     private var mMeasureTextWidth = 0f
  4.     override fun getSize(
  5.         paint: Paint,
  6.         text: CharSequence?,
  7.         start: Int,
  8.         end: Int,
  9.         fontMetricsInt: FontMetricsInt?
  10.     ): Int {
  11.         mMeasureTextWidth = onMeasure(paint, fontMetricsInt, text, start, end)
  12.         // 这段不可以去掉,字体高度没设置,会出现 draw 方法没有被调用的问题
  13.         val metrics = paint.fontMetricsInt
  14.         if (fontMetricsInt != null) {
  15.             fontMetricsInt.top = metrics.top
  16.             fontMetricsInt.ascent = metrics.ascent
  17.             fontMetricsInt.descent = metrics.descent
  18.             fontMetricsInt.bottom = metrics.bottom
  19.         }
  20.         return mMeasureTextWidth.toInt()
  21.     }
  22.     override fun draw(
  23.         canvas: Canvas,
  24.         text: CharSequence?,
  25.         start: Int,
  26.         end: Int,
  27.         x: Float,
  28.         top: Int,
  29.         y: Int,
  30.         bottom: Int,
  31.         paint: Paint
  32.     ) {
  33.         val alpha = paint.alpha
  34.         // 判断是否给画笔设置了透明度
  35.         if (alpha != 255) {
  36.             // 如果是则设置不透明
  37.             paint.alpha = 255
  38.         }
  39.         text?.let {
  40.             onDraw(canvas, paint, it, start, end, x, top, y, bottom)
  41.         }
  42.         // 绘制完成之后将画笔的透明度还原回去
  43.         paint.alpha = alpha
  44.     }
  45.     private fun onMeasure(
  46.         paint: Paint,
  47.         fontMetricsInt: FontMetricsInt?,
  48.         text: CharSequence?,
  49.         @IntRange(from = 0) start: Int,
  50.         @IntRange(from = 0) end: Int
  51.     ): Float {
  52.         return paint.measureText(text, start, end)
  53.     }
  54.     abstract fun onDraw(
  55.         canvas: Canvas,
  56.         paint: Paint,
  57.         text: CharSequence,
  58.         @IntRange(from = 0) start: Int,
  59.         @IntRange(from = 0) end: Int,
  60.         x: Float,
  61.         top: Int,
  62.         y: Int,
  63.         bottom: Int
  64.     )
  65.     fun getMeasureTextWidth(): Float {
  66.         return mMeasureTextWidth
  67.     }
  68. }
复制代码
2.MultiFontSpan
  1. class MultiFontSpan(vararg replacementSpans: ReplacementSpan) : ReplacementSpan() {
  2.     /** 测量的文本宽度  */
  3.     private var mMeasureTextWidth = 0f
  4.     private var mReplacementSpans: List<ReplacementSpan> = mutableListOf()
  5.     init {
  6.         mReplacementSpans = replacementSpans.toList()
  7.     }
  8.     override fun getSize(
  9.         paint: Paint,
  10.         text: CharSequence?,
  11.         start: Int,
  12.         end: Int,
  13.         fm: Paint.FontMetricsInt?
  14.     ): Int {
  15.         for (replacementSpan in mReplacementSpans) {
  16.             val size = replacementSpan.getSize(paint, text, start, end, fm)
  17.             mMeasureTextWidth = Math.max(mMeasureTextWidth, size.toFloat())
  18.         }
  19.         return mMeasureTextWidth.toInt()
  20.     }
  21.     override fun draw(
  22.         canvas: Canvas,
  23.         text: CharSequence?,
  24.         start: Int,
  25.         end: Int,
  26.         x: Float,
  27.         top: Int,
  28.         y: Int,
  29.         bottom: Int,
  30.         paint: Paint
  31.     ) {
  32.         for (replacementSpan in mReplacementSpans) {
  33.             replacementSpan.draw(canvas, text, start, end, x, top, y, bottom, paint)
  34.         }
  35.     }
  36.     override fun updateDrawState(ds: TextPaint?) {
  37.         super.updateDrawState(ds)
  38.         for (replacementSpan in mReplacementSpans) {
  39.             replacementSpan.updateDrawState(ds)
  40.         }
  41.     }
  42.     override fun updateMeasureState(p: TextPaint) {
  43.         super.updateMeasureState(p)
  44.         for (replacementSpan in mReplacementSpans) {
  45.             replacementSpan.updateMeasureState(p)
  46.         }
  47.     }
  48. }
复制代码
3.LinearGradientFontSpan
  1. class LinearGradientFontSpan(
  2.     private val mTextGradientColor: IntArray,     /** 文字渐变颜色组 */
  3.     private val mTextSize: Int? = null,     /** 文字渐变字体大小(字体大小不一致的话这里必须动态设置) */
  4.     private val mTextGradientOrientation: Int? = LinearLayout.VERTICAL,    /** 文字渐变方向 */
  5.     private val mTextGradientPositions: FloatArray? = null,   /** 文字渐变位置组 */
  6. ) : CommonFontSpan() {
  7.     override fun onDraw(
  8.         canvas: Canvas,
  9.         paint: Paint,
  10.         text: CharSequence,
  11.         start: Int,
  12.         end: Int,
  13.         x: Float,
  14.         top: Int,
  15.         y: Int,
  16.         bottom: Int
  17.     ) {
  18.         mTextSize?.let { paint.textSize = it.sp }
  19.         val linearGradient = if (mTextGradientOrientation == LinearLayout.VERTICAL) {
  20.             LinearGradient(0f, 0f, 0f, bottom.toFloat(), mTextGradientColor, mTextGradientPositions, Shader.TileMode.REPEAT)
  21.         } else {
  22.             LinearGradient(x, 0f, x + getMeasureTextWidth(), 0f, mTextGradientColor, mTextGradientPositions, Shader.TileMode.REPEAT)
  23.         }
  24.         paint.shader = linearGradient
  25.         canvas.drawText(text, start, end, x, y.toFloat(), paint)
  26.     }
  27.     override fun getSize(
  28.         paint: Paint,
  29.         text: CharSequence?,
  30.         start: Int,
  31.         end: Int,
  32.         fontMetricsInt: Paint.FontMetricsInt?
  33.     ): Int {
  34.         mTextSize?.let { paint.textSize = it.sp }
  35.         return super.getSize(paint, text, start, end, fontMetricsInt)
  36.     }
  37. }
复制代码
4.StrokeFontSpan
  1. class StrokeFontSpan(
  2.     private val mTextStrokeColor: Int,
  3.     private val mTextStrokeSize: Int,
  4.     private val isSp: Boolean = true,
  5. ) : CommonFontSpan() {
  6.     /** 描边画笔  */
  7.     private val mStrokePaint = Paint()
  8.     override fun onDraw(
  9.         canvas: Canvas,
  10.         paint: Paint,
  11.         text: CharSequence,
  12.         start: Int,
  13.         end: Int,
  14.         x: Float,
  15.         top: Int,
  16.         y: Int,
  17.         bottom: Int
  18.     ) {
  19.         mStrokePaint.set(paint)
  20.         // 设置抗锯齿
  21.         mStrokePaint.isAntiAlias = true
  22.         // 设置防抖动
  23.         mStrokePaint.isDither = true
  24.         mStrokePaint.textSize = paint.textSize
  25.         // 描边宽度
  26.         mStrokePaint.strokeWidth = if (isSp) mTextStrokeSize.dp else mTextStrokeSize.toFloat()
  27.         mStrokePaint.style = Paint.Style.STROKE
  28.         // 设置粗体
  29.         paint.isFakeBoldText = paint.typeface === Typeface.DEFAULT_BOLD
  30.         mStrokePaint.color = mTextStrokeColor
  31.         canvas.drawText(text, start, end, x, y.toFloat(), mStrokePaint)
  32.         canvas.drawText(text, start, end, x, y.toFloat(), paint)
  33.     }
  34. }
复制代码
5.使用
  1. SpanUtils.with(mBindView.tvAnswerBtn1)
  2.             .append("豆奶")
  3.             .setSpans(StrokeFontSpan(Color.WHITE, 1))
  4.             .append("好喝")
  5.             .setSpans(LinearGradientFontSpan(intArrayOf(Color.RED, Color.BLUE)))
  6.             .append("还要")
  7.             .setSpans(
  8.                 MultiFontSpan(
  9.                     StrokeFontSpan(Color.GREEN, 2),
  10.                     LinearGradientFontSpan(intArrayOf(Color.WHITE, Color.YELLOW))
  11.                 )
  12.             )
  13.             .create()
复制代码
设置渐变字体 巨细差别
  1. val colors = intArrayOf(Color.parseColor("#FDF4E9"), Color.parseColor("#FFDD63"))
  2.         SpanUtils.with(mBindView.tvMaxMoney)
  3.             .append("30")
  4.             .setBold()
  5.             .setSpans(LinearGradientFontSpan(colors, 100))
  6.             .append("元")
  7.             .setSpans(LinearGradientFontSpan(colors, 32))
  8.             .create()
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

盛世宏图

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表