安卓知识笔记(五)Canvas实现图文排版

Canvas实现图文排版


前言

沉默之后的爆发是最恐怖的


一、效果图

在这里插入图片描述

二、利用breakText可以获取当前宽度最多画多少个字

 //计算当前的画笔最多能写多少个字
count = textPaint.breakText(msg, startCount, msg.length, true, maxWidth, measureWidth)

三、利用FontMetrics可以拿到当前画笔的top、ascent、descent、bottom、leading,由此可算出一行的高度

   maxWidth =
                //判断当前的高度是不是小于图片的marginTop或者大于图片高度+marginTop
                if (offset + fontMetrics.bottom < 60f.px || offset + fontMetrics.top > IMAGE_SIZE+60f.px) {
                    //直接写完全屏
                    width.toFloat()
                } else {
                    //只能写到图片的左边
                    width - IMAGE_SIZE
                }

四、完整代码

package com.jbh.study.widget

import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.Paint
import android.text.TextPaint
import android.util.AttributeSet
import android.view.View
import com.jbh.study.R
import com.jbh.study.ext.px
import kotlin.math.max

/**
 * @author bingHao.Ji
 * @date 2021/8/19.
 * description:
 */
class MultiTextView : View {
    val msg: String =
        "汉皇重色思倾国,御宇多年求不得。杨家有女初长成,养在深闺人未识。天生丽质难自弃,一朝选在君王侧。回眸一笑百媚生,六宫粉黛无颜色。春寒赐浴华清池,温泉水滑洗凝脂。侍儿扶起娇无力,始是新承恩泽时。云鬓花颜金步摇,芙蓉帐暖度春宵。春宵苦短日高起,从此君王不早朝。承欢侍宴无闲暇,春从春游夜专夜。后宫佳丽三千人,三千宠爱在一身。金屋妆成娇侍夜,玉楼宴罢醉和春。姊妹弟兄皆列土,可怜光彩生门户。遂令天下父母心,不重生男重生女。骊宫高处入青云,仙乐风飘处处闻。缓歌慢舞凝丝竹,尽日君王看不足。渔阳鼙鼓动地来,惊破霓裳羽衣曲。九重城阙烟尘生,千乘万骑西南行。翠华摇摇行复止,西出都门百余里。六军不发无奈何,宛转蛾眉马前死。花钿委地无人收,翠翘金雀玉搔头。君王掩面救不得,回看血泪相和流。黄埃散漫风萧索,云栈萦纡登剑阁。峨嵋山下少人行,旌旗无光日色薄。蜀江水碧蜀山青,圣主朝朝暮暮情。行宫见月伤心色,夜雨闻铃肠断声。 天旋地转回龙驭,到此踌躇不能去。马嵬坡下泥土中,不见玉颜空死处。"
    val textPaint = TextPaint(Paint.ANTI_ALIAS_FLAG).apply {
        textSize = 18f.px
    }

    val fontMetrics = Paint.FontMetrics()
    val IMAGE_SIZE = 100f.px

    constructor(context: Context?) : super(context)
    constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(
        context,
        attrs,
        defStyleAttr
    )

    override fun onDraw(canvas: Canvas) {
        //绘制图片
        canvas.drawBitmap(
            getAvatarBitmap(IMAGE_SIZE.toInt()),
            width - IMAGE_SIZE,
            60f.px,
            textPaint
        )
        //根据当前画笔拿到fontMetrics的top和bottom
        textPaint.getFontMetrics(fontMetrics)
        val measureWidth = floatArrayOf(0f)
        var startCount = 0
        var count: Int
        var offset = -fontMetrics.top
        var maxWidth: Float
        while (startCount < msg.length) {
            maxWidth =
                //判断当前的高度是不是小于图片的marginTop或者大于图片高度+marginTop
                if (offset + fontMetrics.bottom < 60f.px || offset + fontMetrics.top > IMAGE_SIZE+60f.px) {
                    //直接写完全屏
                    width.toFloat()
                } else {
                    //只能写到图片的左边
                    width - IMAGE_SIZE
                }
            //计算当前的画笔最多能写多少个字
            count = textPaint.breakText(msg, startCount, msg.length, true, maxWidth, measureWidth)
            //画出对应的文字
            canvas.drawText(msg, startCount, startCount + count, 0f, offset, textPaint)
            startCount += count
            offset += textPaint.fontSpacing

        }
    }


    private fun getAvatarBitmap(width: Int): Bitmap {
        val options = BitmapFactory.Options()
        options.inJustDecodeBounds = true
        BitmapFactory.decodeResource(resources, R.mipmap.zzt, options)
        options.inJustDecodeBounds = false
        options.inDensity = options.outWidth
        options.inTargetDensity = width
        return BitmapFactory.decodeResource(resources, R.mipmap.zzt, options)
    }
}

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值