我花了好几个小时寻找答案,并且真的不知道如何解决它。所以,让我们开展业务:
有一张图片和TextView
,我需要在TextView
周围流动ImageView
,如下所示:
第一种可能的解决方案是使用https://github.com/deano2390/FlowTextView,但它没有扩展TextView
因此,由于多种原因,这个库不适合我。
第二个解决方案是使用LeadingMarginSpan.LeadingMarginSpan2
span,但它会影响文本中每n行的每个段落(如此答案 - > How to layout text to flow around an image),所以我得到这样的东西:
但我只想为前n行设置保证金!然后我决定实现LeadingMarginSpan.Standart
并创建一个计数器并在getLeadingMargin(first: Boolean): Int
函数调用中递增它。当计数器达到理想值时,函数返回0作为边距宽度。再次失败了!文本向左移动而不是传播到视图的末尾,而不是填充TextView
行。
UPD:是的,我在这里使用了onGlobalLayoutListener
好吧,谷歌搜索另一个解决方案我找到了这个答案https://stackoverflow.com/a/27064368/7218592 好的,我已完成了所描述的所有内容并实现了代码:
//set left margin of desirable width
val params: RelativeLayout.LayoutParams = RelativeLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
params.leftMargin = holder.imageContainerHeight!!
params.addRule(RelativeLayout.BELOW, holder.mNumberAndTimeInfo!!.id)
holder.mCommentTextView!!.layoutParams = params
if (holder.commentTextViewOnGlobalLayoutListener != null)
holder.mCommentTextView!!.viewTreeObserver.removeOnGlobalLayoutListener(
holder.commentTextViewOnGlobalLayoutListener)
//add onGlobalLayoutListener
holder.mCommentTextView!!.viewTreeObserver.addOnGlobalLayoutListener(
if (holder.commentTextViewOnGlobalLayoutListener != null)
holder.commentTextViewOnGlobalLayoutListener
else CommentTextViewOnGlobalLayoutListener(holder,
SpannableString(HtmlCompat.fromHtml(
mView.getActivity(), commentDocument.html(), 0,
null, SpanTagHandlerCompat(mView.getActivity())))))`
我的OnGlobalLayoutListener
看起来像这样:`
class CommentTextViewOnGlobalLayoutListener(
val holder: CommentAndFilesListViewViewHolder, val commentSpannable: Spannable) :
ViewTreeObserver.OnGlobalLayoutListener {
val LOG_TAG: String = CommentTextViewOnGlobalLayoutListener::class.java.simpleName
override fun onGlobalLayout() {
holder.mCommentTextView!!.viewTreeObserver.removeGlobalOnLayoutListener(this)
//when textview layout is drawn, get the line end to spanify only the needed text
val charCount = holder.mCommentTextView!!.layout.getLineEnd(Math.min(
holder.mCommentTextView!!.layout.lineCount - 1,
CommentLeadingMarginSpan.computeLinesToBeSpanned(holder)))
if (charCount <= commentSpannable.length) {
commentSpannable.setSpan(CommentLeadingMarginSpan(holder),
0, charCount, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
//set the left margin back to zero
(holder.mCommentTextView!!.layoutParams as RelativeLayout.LayoutParams).leftMargin = 0
holder.mCommentTextView!!.text = commentSpannable
}
}
`
嗯,它有效。但是它有多糟糕!当我使用视图持有者模式时,我必须将一个变量保存到侦听器并删除它是否未被调用并成功删除,因为onGlobalLayout
函数没有及时调用!它被称为太晚了,所以你需要等待大约300毫秒,然后观看所有重建&#34; TextView
而且看起来很恶心!
所以,我的问题是:
在用户界面上绘制之前,如何在TextView
中为第一个 n行创建边距?
答案 0 :(得分:0)
这只是一个建议,只有经过反复尝试才能起作用
这段代码使用多行编辑文本
btnPrint.setOnClickListener {
val str = """
One
Two
Three
Now click Action Button Custom SB
""".trimIndent()
etNews.setText(str)
}
使用缩进一号值和trimIndent值进行播放