【问题标题】:Flow textview around image围绕图像流动文本视图
【发布时间】: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


【解决方案1】:

这更像是一个建议,只能通过一些试验和错误来工作
此代码使用多行编辑文本

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

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

【讨论】:

    猜你喜欢
    • 2014-07-07
    • 1970-01-01
    • 2011-01-15
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-07-02
    • 1970-01-01
    相关资源
    最近更新 更多