【发布时间】:2018-01-19 11:38:09
【问题描述】:
我花了几个小时寻找答案,但真的不知道如何解决它。那么让我们开始吧:
有一个图像和一个TextView,我需要像这样在ImageView 周围流动TextView:
第一个可能的解决方案是使用https://github.com/deano2390/FlowTextView,但它没有扩展TextView,所以这个库不适合我,原因有很多。
第二种解决方案是使用LeadingMarginSpan.LeadingMarginSpan2 span,但它会影响文本中每 n 行的 each 段落(如在此答案中 -> 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毫秒,然后观看TextView的所有“重构”,看起来很恶心!
所以,我的问题是:
如何为TextView 中的前 n 行设置边距,然后在 UI 上绘制?
【问题讨论】:
-
我会在这里尝试不同的方法,我会在这里使用 webview 并在那里设置图像和文本
-
Webview 不是一个选项,因为我需要处理几个自定义的可点击跨度。我不能放弃他们:(
-
我认为问题是在here 引入的,可能重复。
标签: android user-interface kotlin textview