宁波网站建设鲤斯设计,游戏网站上图片动态怎么做的,静态网页设计代码模板,网站建设中html网页在 Android 开发中#xff0c;TextView 是一个非常基础和常用的用户界面组件#xff0c;用于在屏幕上显示文本内容。TextView 继承自 View 类#xff0c;并提供了展示文本以及相关样式处理的功能。
TextView 允许开发者在应用程序的用户界面中显示格式化的文本内容。它支持…在 Android 开发中TextView 是一个非常基础和常用的用户界面组件用于在屏幕上显示文本内容。TextView 继承自 View 类并提供了展示文本以及相关样式处理的功能。
TextView 允许开发者在应用程序的用户界面中显示格式化的文本内容。它支持修改字体大小、字体颜色、文本对齐方式、行间距等多种属性来控制文本的显示样式。同时TextView 也支持一些高级功能如文本阴影、文本装饰如下划线和删除线、跑马灯效果文本的滚动显示等。 最近在检测性能中发现 RecycleView 在滑动过程中的 TextView.setText() 有一些耗时从主观上体验也会有一点卡顿然后进入源码看看是怎么回事 UnsupportedAppUsageprivate void setText(CharSequence text, BufferType type,boolean notifyBefore, int oldlen) {// ...if (mLayout ! null) {checkForRelayout();}} setText() 的代码量还不少看到有个 checkForRelayout()进去看看 UnsupportedAppUsageprivate void checkForRelayout() {if ((mLayoutParams.width ! LayoutParams.WRAP_CONTENT || //...)) {//...requestLayout();invalidate();} else {nullLayouts();requestLayout();invalidate();}}
在 checkForRelayout() 当中是一定会调用 requestLayout() 的也就是说 TextView.setText() 通常是会调用 requestLayout()
首先需要复习一下 Android 的布局流程 测量阶段Measure 在这个阶段系统会根据视图的 LayoutParams 和父布局的规格递归地计算出每一个视图的尺寸大小即宽度和高度。这个过程涉及到调用每个视图的 onMeasure(int widthMeasureSpec, int heightMeasureSpec) 方法。
布局阶段Layout 测量完成之后系统会知道所有视图的大小接下来就是确定它们在父布局中的位置。这个过程涉及到调用每个视图的 onLayout(boolean changed, int left, int top, int right, int bottom) 方法。
绘制阶段Draw 最后是绘制过程系统会调用每个视图的 onDraw(Canvas canvas) 方法将视图绘制到屏幕上。 当调用 requestLayout() 方法时它会标记这个视图树需要一个新的布局系统会安排一个新的布局过程在这个过程中会重新执行测量Measure和布局Layout步骤。
而测量和布局阶段都可能是耗时的操作特别是在复杂的布局结构或大型视图树中。这是因为测量和布局阶段需要计算视图及其子视图的尺寸和位置并且这个计算可能是递归的。
对于一个单独的 TextView 而言调用 setText() 后重新进行测量、布局和绘制来更新视图没什么问题。但是当在 RecycleView 中TextView 很多情况下只是单纯的更换 String布局不会发生改动。这个时候我们就可以自定义一个在 setText() 时不会 requestLayout() 的 TextView 来优化性能 为了能和 TextView 一样在 xml 上设置属性需要在 style 文件增加
resourcesdeclare-styleable nameSimpleTextViewattr nameandroid:text formatstring /attr nameandroid:textColor formatcolor /attr nameandroid:textSize formatdimension|reference /attr nameandroid:singleLine formatboolean /attr nameandroid:textStyleenum namenormal value0 /enum namebold value1 /enum nameitalic value2 //attr/declare-styleable
/resources
自定义的 TextView
class SimpleTextView JvmOverloads constructor(context: Context, attrs: AttributeSet? null, defStyleAttr: Int 0
) : View(context, attrs, defStyleAttr) {private var text: String? private var singleLine falseprivate val textPaint TextPaint(Paint.ANTI_ALIAS_FLAG)init {val typedArray context.obtainStyledAttributes(attrs, R.styleable.SimpleTextView)text typedArray.getString(R.styleable.SimpleTextView_android_text) ?: singleLine typedArray.getBoolean(R.styleable.SimpleTextView_android_singleLine, false)textPaint.color typedArray.getColor(R.styleable.SimpleTextView_android_textColor, Color.BLACK)textPaint.textSize typedArray.getDimensionPixelSize(R.styleable.SimpleTextView_android_textSize, 40).toFloat()textPaint.typeface Typeface.create(Typeface.DEFAULT, typedArray.getInt(R.styleable.SimpleTextView_android_textStyle, 0))typedArray.recycle()}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {val minHeight paddingTop textPaint.descent() - textPaint.ascent() paddingBottom// 设置视图大小setMeasuredDimension(widthMeasureSpec,resolveSize(minHeight.toInt(), heightMeasureSpec))}override fun onDraw(canvas: Canvas?) {super.onDraw(canvas)canvas ?: returnval baseline paddingTop - textPaint.ascent() // 文本基线val textWidth width - paddingLeft - paddingRight // 文本显示宽度val textToShow if (singleLine textPaint.measureText(text) textWidth) {TextUtils.ellipsize(text, textPaint, textWidth.toFloat(), TextUtils.TruncateAt.END).toString()} else {text}// 绘制文本canvas.drawText(textToShow!!, paddingLeft.toFloat(), baseline, textPaint)}fun setText(text: String?) {text ?: returnthis.text text}
}
这里我在 onMeasure 设置视图大小的时候宽度给的是最大值因为只测量一次之后输入的文本长度即使是不一样的也都能够兼容到。配合 singleLine 的效果就能做到高性能的单行显示效果了 本片文章的核心思想是减少 RecycleView 中 TextView 不必要的测量和布局步骤从而优化卡顿问题。若 TextView 的测量、布局和绘制都是必要的则需要从其他方面去入手优化了