图像

时间:2017-08-11 04:27:40

标签: android user-interface kotlin textview

我花了好几个小时寻找答案,并且真的不知道如何解决它。所以,让我们开展业务:

有一张图片和TextView,我需要在TextView周围流动ImageView,如下所示:

enter image description here

第一种可能的解决方案是使用https://github.com/deano2390/FlowTextView,但它没有扩展TextView因此,由于多种原因,这个库不适合我。

第二个解决方案是使用LeadingMarginSpan.LeadingMarginSpan2 span,但它会影响文本中每n行的每个段落(如此答案 - > How to layout text to flow around an image),所以我得到这样的东西:

enter image description here

但我只想为前n行设置保证金!然后我决定实现LeadingMarginSpan.Standart并创建一个计数器并在getLeadingMargin(first: Boolean): Int函数调用中递增它。当计数器达到理想值时,函数返回0作为边距宽度。再次失败了!文本向左移动而不是传播到视图的末尾,而不是填充TextView行。

UPD:是的,我在这里使用了onGlobalLayoutListener

enter image description here

好吧,谷歌搜索另一个解决方案我找到了这个答案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行创建边距?

1 个答案:

答案 0 :(得分:0)

这只是一个建议,只有经过反复尝试才能起作用
这段代码使用多行编辑文本

        btnPrint.setOnClickListener {
        val str = """
        One
        Two
        Three
        Now click Action Button Custom SB
        """.trimIndent()
        etNews.setText(str)
    }

使用缩进一号值和trimIndent值进行播放