刚接到这个需求的时候,我没有在意,原来有这个功能不就改个UI能有多难,1小时搞定,直到摔了一次又一次,我才意识到(我大意了,没有闪),效果如下(动效就是,飘屏从屏幕的右边漂到左边)
因为TextView的背景要跟随文字变长,同时背景也比较复杂,所以必须用到.9,所以我用Android Studio制作了.9图(不会做的可以去百度)
第一个坑 设置.9图后,文字不显示
将.9图设置成为背景之后,字没了,人傻了,解决方案
TextView在调用 setBackgroundResource方法之后,再调用 setPadding方法,示例如下
textview.setBackgroundResource(R.drawable.img_bg);
textview.setPadding(20, 0, 20, 0)
原因是因为.9图 自带内边距,需要重新设置内边距
第二个坑 paddingleft 需要设置很大,才能显示出来字
设置完padding之后字还是没显示,我以为设置的pading太小,最后设置到120dp字才正常显示出来和背景对齐,然后我就看了一下.9图,切的图自带超长左边距,呼叫UI小姐姐重新切图
第三个坑 .9图不生效
.9图如果没有生效,则不会随着文字长度而有所改变,不生效的原因有以下三个:
- 确保.9图片在drawable目录下
- 确保你的mipmap/drawable目录下,没有和.9图片重名(此处的重名是指,排除文件后缀的重名,例如: back.png和back.9.png属于同名)的文件,如果有,删除掉mipmap/drawable目录下的同名文件
3.上面操作都做了还不生效的话,那么就在你的把.9图片移动到drawable-xxhdpi的目录下(我踩到的就是这个)
第四个坑 当文字超过屏幕宽度的时候textView展示不全
view显示不全产生的原因无非就两种一种是view本身宽高不够,另外一种是父view给的宽高不够,针对显示不全一般通过背景颜色设置法和固定宽高法进行分析。我们给父View和TextView设置不同的背景色,然后给父view的LayoutParams设置固定宽度,分析出来是父view给的宽度不够。
//飘屏准备view
override fun providerDefaultView(type: Int): View {
//这种写法不是Compose,只是高级函数的实现,后面文章会介绍
val view = ConstraintLayout {
layout_width = wrap_content
layout_height = 72
//给父view设置白色
background_color_res=R.color.white
TextView {
layout_id = "tv"
layout_width = wrap_content
layout_height = 72
maxLines = 1
textSize = 12f
gravity = gravity_center
fontFamily = R.font.pingfang
start_toEndOf = "iv_start"
center_vertical = true
//子view设置红色
background_color_res=R.color.red
}
...
}
return view!!
}
//给View填充数据,并设置到派对底层View中
override fun readyView(type: Int, view: View) {
view.apply {
...
val textView = find<TextView>("tv")
//span 文字包括图片(后面会有文章详解 SpanUtils()的实现)
val spanUtils=SpanUtils().append("...")...
//textview设置内容
textView?.text = spanUtils.create()
textView?.setBackgroundResource(R.drawable.img_bg)
textView?.setPadding(20, 0, 20, 0)
//给lp设置500dp后果然显示全了
val lp = ConstraintLayout.LayoutParams(
500.dp,
60.dp
)
lp.topToBottom = R.id.tv_theme
lp.startToEnd = ConstraintLayout.LayoutParams.PARENT_ID
//这快看不懂没关系,后面会有飘屏实现文章会讲这块
lp.bottomToBottom = ConstraintLayout.LayoutParams.UNSET
lp.startToStart = ConstraintLayout.LayoutParams.UNSET
lp.endToEnd = ConstraintLayout.LayoutParams.UNSET
lp.endToStart = ConstraintLayout.LayoutParams.UNSET
//将view填充到派对的根布局中
constraintLayout?.addView(this, lp)
}
}
解决方案:刚开始没看到底下的addView() 用textView?.measuredWidth结果获得是值为0,因为子view的onMeasure()会在调用了requestLayout()后触发,measuredWidth只有在onMearsure()方法执行才能获取到测量后的宽度,addView会调用addViewInner,而addViewInner()在设置新的LayoutParam则会调用子view的requestLayout(),所以在addview之前通过measuredWidth获取不到宽度,只能使用如下方式去计算TextView的宽度然后再加上别的View的宽度以及间距就是整个View的大概所需的宽度
override fun readyView(type: Int, view: View) {
view.apply {
...
//设置字体大小然后算出textview的内容会占多宽
val paint = Paint()
paint.textSize = 12f
val strWidth = paint.measureText(textView.text.toString()) + 56
//设置View的整体宽度
val lp = ConstraintLayout.LayoutParams(
strWidth.toInt().dp,
60.dp
)
...
constraintLayout?.addView(this, lp)
}
完结,撒花🎉