围绕图像流动textview

kor*_*iku 8 user-interface android textview kotlin

我花了几个小时寻找答案,真的不知道如何解决它.让我们开始做生意:

有一个形象,一个TextView和我需要的流动TextView围绕ImageView这样的:

在此输入图像描述

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

第二个解决方案是使用LeadingMarginSpan.LeadingMarginSpan2span,但它会影响文本中每n行的每个段落(比如在这个答案 - > 如何布局文本以围绕图像流动),所以我得到像这样的smth:

在此输入图像描述

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

UPD:是的,我onGlobalLayoutListener在这里用过

在此输入图像描述

好吧,谷歌搜索另一个解决方案,我发现这个答案/sf/answers/1894505791/ 好的,我已完成所描述的一切并实现了代码:

            //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())))))`
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

`

嗯,它的工作原理.但是它有多糟糕!因为我正在使用视图持有者模式,我必须将一个变量保存到侦听器并删除它是否未被调用并成功删除,因为onGlobalLayout函数未及时调用!它被称为太晚了,所以你需要等待大约300毫秒,然后观看所有的"重建",TextView它看起来很恶心!

所以,我的问题是: 如何在UI上绘制之前为 n行创建边距TextView

Vec*_*tor 0

这更多的是一个建议,仅需要一点点试验和错误
此代码使用多行编辑文本

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

使用一两个值 indent 和 trimIndent 还有其他可用属性