首页 > 其他分享 >android在一个TextView中设置不同字体大小、不同字体颜色封装

android在一个TextView中设置不同字体大小、不同字体颜色封装

时间:2024-07-23 09:52:07浏览次数:8  
标签:ColorSizeTextView 字体大小 val EXCLUSIVE index spannableString length android TextVi

一、概述

  在开发过程中遇到过这样一种业务,有很多单行文本字体。字符串中每一部分的字体样式、大小、颜色都不相同。传统的做法是放多个TextView以达到效果。

  但是当这个页面中的这样的元素非常多,且非常复杂的时候,就会出现页面加载缓慢的问题(view加载=深度(递归)+平铺),也就是页面元素越多,层级越深加载速度越慢。

  此时如果能把本来要用四五个TextView才能完成的事情用一个TextView完成,这样就能大大提高页面加载速度。

  示例图:

 

  

二、代码示例(直接复制粘贴可用)

  1.封装类:ColorSizeTextView.kt

package com.yw.custommutilimageadapter.widget

import android.content.Context
import android.graphics.Color
import android.text.SpannableString
import android.text.Spanned
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.util.AttributeSet
import android.util.Log
import androidx.appcompat.widget.AppCompatTextView
import com.yw.custommutilimageadapter.R
import java.lang.StringBuilder


/**
 * 可改变字颜色和字体大小的TextView
 * 即一个字体中可以有不同的字体颜色和字体大小
 */
class ColorSizeTextView(context: Context, attrs: AttributeSet?) :
    AppCompatTextView(context, attrs) {
    init {
        val a = context.obtainStyledAttributes(attrs, R.styleable.ColorSizeTextView)

        val textColor1 = a.getColor(R.styleable.ColorSizeTextView_textColor1, Color.BLACK)
        val textSize1 = a.getDimension(R.styleable.ColorSizeTextView_textSize1, 12f)
        val textContent1 = a.getString(R.styleable.ColorSizeTextView_textContent1)

        val textColor2 = a.getColor(R.styleable.ColorSizeTextView_textColor2, Color.BLACK)
        val textSize2 = a.getDimension(R.styleable.ColorSizeTextView_textSize2, 12f)
        val textContent2 = a.getString(R.styleable.ColorSizeTextView_textContent2)

        val textColor3 = a.getColor(R.styleable.ColorSizeTextView_textColor3, Color.BLACK)
        val textSize3 = a.getDimension(R.styleable.ColorSizeTextView_textSize3, 12f)
        val textContent3 = a.getString(R.styleable.ColorSizeTextView_textContent3)
        val isLayout = a.getBoolean(R.styleable.ColorSizeTextView_isLayout, false)


        Log.e("ColorSizeTextView:", "$textSize1,$textSize2,$textSize3")

        if (isLayout) {
            // 创建一个SpannableString对象
            val spannableString = SpannableString("$textContent1$textContent2$textContent3")
            // 设置第一部分文本的字体大小和颜色
            spannableString.setSpan(
                AbsoluteSizeSpan(textSize1.toInt()),
                0,
                textContent1?.length!!,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            spannableString.setSpan(
                ForegroundColorSpan(textColor1),
                0,
                textContent1?.length!!,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            //设置第二部分文本的字体大小和颜色
            spannableString.setSpan(
                AbsoluteSizeSpan(textSize2.toInt()),
                textContent1.length,
                textContent1.length + textContent2?.length!!,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            spannableString.setSpan(
                ForegroundColorSpan(textColor2),
                textContent1.length,
                textContent1.length + textContent2.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )

            //设置第三部分文本的字体大小和颜色
            spannableString.setSpan(
                AbsoluteSizeSpan(textSize3.toInt()),
                textContent1.length + textContent2.length,
                spannableString.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            spannableString.setSpan(
                ForegroundColorSpan(textColor3),
                textContent1.length + textContent2.length,
                spannableString.length,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            text = spannableString
            a.recycle()
        }
    }

    fun setSizeColorData(datas: ArrayList<ColorSizeData>) {
        val sbContent = StringBuilder()
        datas.forEachIndexed { index, colorSizeData ->
            sbContent.append(colorSizeData.content)
        }
        // 创建一个SpannableString对象
        val spannableString = SpannableString(sbContent.toString())
        var startIndex = 0
        var endIndex = 0

//        for (index in 0 until datas.size) {
//            endIndex += datas[index].content?.length!!
//            if (index > 0) {
//                startIndex += datas[index - 1].content?.length!!
//            }
//            Log.e("ColorSizeTextView:", "$startIndex,$endIndex")
//        }

        for (index in 0 until datas.size) {
            endIndex += datas[index].content?.length!!
            if (index > 0) {
                startIndex += datas[index - 1].content?.length!!
            }
            Log.e("ColorSizeTextView:", "$startIndex,$endIndex")
            Log.e("ColorSizeTextView---size:", "${datas[index].textSize}")
            // 设置第一部分文本的字体大小和颜色
            spannableString.setSpan(
                AbsoluteSizeSpan(datas[index].textSize),
                startIndex,
                endIndex,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
            spannableString.setSpan(
                ForegroundColorSpan(datas[index].textColor),
                startIndex,
                endIndex,
                Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
            )
        }

        text = spannableString
    }

    class ColorSizeData(
        var textColor: Int,
        var textSize: Int,
        var content: String?
    )
}

  2.用法

tvContent.setSizeColorData(ArrayList<ColorSizeTextView.ColorSizeData>().apply {
            add(
                ColorSizeTextView.ColorSizeData(
                    Color.parseColor("#3700B3"),
                    PxUtils.sp2px(this@TextViewDifferentColorAndSizeActivity,14f),
                    "德玛西亚啊"
                )
            )
            add(
                ColorSizeTextView.ColorSizeData(
                    Color.parseColor("#FF7201"),
                    PxUtils.sp2px(this@TextViewDifferentColorAndSizeActivity,12f),
                    "诺克萨斯33333333333333333"
                )
            )
            add(
                ColorSizeTextView.ColorSizeData(
                    Color.parseColor("#333333"),
                    PxUtils.sp2px(this@TextViewDifferentColorAndSizeActivity,10f),
                    "光辉女郎寒冰射手牛逼库拉斯"
                )
            )
        })

 

标签:ColorSizeTextView,字体大小,val,EXCLUSIVE,index,spannableString,length,android,TextVi
From: https://www.cnblogs.com/tony-yang-flutter/p/18317607

相关文章

  • Android开发 - Context解析
    Context是什么Context的中文翻译为:语境;上下文;背景;环境,在开发中我们经常说称之为“上下文”,那么这个“上下文”到底是指什么意思呢?在语文中,我们可以理解为语境,在程序中,我们可以理解为当前对象在程序中所处的一个环境,一个与系统交互的过程。比如微信聊天,此时的“环境”是指......
  • Android开发 - Bundle传值的理解与使用
    什么是BundleBundle经常出现在以下场合:Activity状态数据的保存与恢复涉及到的两个回调:voidonSaveInstanceState(BundleoutState)voidonCreate(BundlesavedInstanceState)Fragment的setArguments方法:voidsetArguments(Bundleargs)消息机制中的Message的setData......
  • TextView实现原理分析
    TextView是Android中用于显示文本的核心组件,它的实现原理涉及多个方面,包括文本渲染、布局计算、滚动支持等。下面,我将结合源码分析TextView的关键实现细节。1.构造和初始化TextView是View的子类,同时继承自AppCompatTextView或MaterialTextView,这些类又继承自and......
  • Android 常见面试题(一)
    Android常见面试题(一)1、java中==和equals和hashCode的区别基本数据类型的==比较的值相等.类的==比较的内存的地址,即是否是同一个对象。在不重写equals方法的情况下,equals同比较内存地址,原实现也为==,如String等重写了equals方法,会判断字符串里的值是否相等......
  • Android4.4.4双声卡同时出声
    在调试RK3288Android4.4.4,该方案默认配置上SPDIF时HDMI就没声音,但客户需求是同时要有声音的,于是驱动配置上后,呈现两个声卡状态,此时需要通过修改HAL层来处理(RK3288Android4.4.4对应的HAL层源码为hardware/rk29/audio目录),修改如下:1.修改AudioHardware.cpp文件,在AudioHardware:......
  • Android或iOS 与 REST/SOAP测试 工具推荐
    移动测试工具- 有助于自动测试Android或iOS应用程序1)AppiumAppium是用于移动应用程序自动化的开源测试工具之一。它允许用户测试各种原生、移动、web和混合应用程序。它还支持模拟器和模拟器上的自动测试。功能特点:这是一个简单的应用程序,需要很少的内存用于测试过程......
  • Android笔试面试题AI答之控件Views(3)
    答案仅供参考,来自文心一言目录1.如何在ListView间添加分割线?方法1:在XML布局文件中设置方法2:在Java代码中设置注意事项2.如何实现ListView的逐行显示?1.使用`Handler`和`postDelayed()`方法2.监听滚动事件3.自定义Adapter4.使用`RecyclerView`代替`ListVie......
  • Android 14 适配之— BluetoothAdapter、JobScheduler、 Tiles
    1. BluetoothAdapter改动:在BluetoothAdapter中必须加入 BLUETOOTH_CONNECT权限 Android14(API级别34)或更高版本为目标的App,在调用函数 BluetoothAdapter getProfileConnectionState() 时,需要 BLUETOOTH_CONNECT 权限,<uses-permissionandroid:name="android......
  • Android14 - 前台服务、图片选择器 、OpenJDK 17、其他适配
    前台服务1.指定前台服务类型   以Android14(API级别34)或更高版本为目标平台的应用,需要为应用中的每项前台服务指定服务类型,因为系统需要特定类型的前台服务满足特定用例。具体介绍如下:   在Android10在 <service> 元素内引入了 android:foregroundService......
  • android Activity生命周期
    (1)activity启动政策:activity启动行为由相应应用的 AndroidManifest.xml 文件中的启动模式、intent标志以及调用方提供的ActivityOptions定义。使用 ActivityOption#setLaunchDisplayId(int) 可将特定屏幕指定为activity启动的目标。默认情况下,activity与调用方在......