【问题标题】:Spannable text that holding custom view包含自定义视图的可扩展文本
【发布时间】:2020-09-13 12:22:39
【问题描述】:

是否可以将自定义视图添加到可跨文本中?

android.text.style 包中,我可以看到许多类型的可跨对象,但我想知道是否可以添加自定义视图。

类似于spanable.setSpan(CustomView, .. , .. ,..)

请注意:CustomView 可能是任何类型的视图,即:WebView

【问题讨论】:

  • 问题应该是是否建议添加一个视图作为对Spannable 的引用。由于视图包含上下文并且可扩展字符串未绑定到任何生命周期,因此不应将引用放在那里。
  • @tynn 你对视图的上下文/生命周期是正确的?...但是在 WeakHashMap 中保存引用并在我离开 SpannableText MainView 后销毁它们呢?所以我的问题仍然存在......是否可以将自定义视图注入到可扩展文本中?
  • 您只是希望自定义视图在文本中显示为图像吗?这将是因为它会出现在 ViewGroup 中但适合文本边界?您是否希望自定义视图在其显示之外也可操作,即可点击、接受焦点、可编辑等?
  • @Cheticamp 我认为自定义视图不能提供超出显示属性的功能。虽然我可以像使用<a href 那样处理点击,但现在我试图将它们显示为图像最少。
  • 一个 ImageSpan 将在文本中显示一个图像,但您需要一个位图或自定义视图中的某种可绘制对象。如果 ImageSpan 有效,您的问题是否会简化为如何从自定义视图中获取位图或可用于 ImageSpan 的内容? (我不认为 wonsuc 的答案太遥远。我质疑关于 ViewGroups 的说法,但据我所知,@wonsuc 的答案与动画无关。)

标签: android html android-view android-spannable


【解决方案1】:

在 Android 中,只有 ViewGroup 类可以包含另一个视图,因此说起来很恰当,

是否可以将可跨文本添加到自定义视图中?

如果您的自定义视图扩展了ViewGroup 类,那么答案是

但是,如果您想使用 spannable 绘制特定的图形或动画,则需要直接从自定义视图中绘制 Canvas

例如,如果您检查android.text.style 包中的DynamicDrawableSpan 类。

@Override
public void draw(@NonNull Canvas canvas, CharSequence text,
        @IntRange(from = 0) int start, @IntRange(from = 0) int end, float x,
        int top, int y, int bottom, @NonNull Paint paint) {
    Drawable b = getCachedDrawable();
    canvas.save();

    int transY = bottom - b.getBounds().bottom;
    if (mVerticalAlignment == ALIGN_BASELINE) {
        transY -= paint.getFontMetricsInt().descent;
    } else if (mVerticalAlignment == ALIGN_CENTER) {
        transY = (bottom - top) / 2 - b.getBounds().height() / 2;
    }

    canvas.translate(x, transY);
    b.draw(canvas);
    canvas.restore();
}

它有draw 方法,可以直接在Canvas 上绘制Drawable,如果你想创建自定义的可跨类,它会比现有的SDK 类显示更多的东西。

【讨论】:

    【解决方案2】:

    所以看起来使用 Spannable 的方式来处理这种情况会很有挑战性。

    因此我创建了一个new library 来处理标签,这样我就可以在任何我想要的地方使用它们。

    这是一个例子

    HtmlParser.Builder(StringSource(source)).setCallback(object : HtmlParser.ParserCallbacks {
    override fun onParseFinished(list: List<Element>) {
    list.forEach {
            Log.d(TAG, "onParseFinished: ${ElementType.values()[it.type]} ||| ${it.toString()}")
        if (it is ImageElement) {
            Log.d(TAG, "onImageFound: $it ||| ${it.ImageUrl}")
        } else if (it is IFrameElement) {
            Log.d(TAG, "onIFrameFound: $it ||| ${it.url}")
        } else if (it is BlockQuoteElement) {
            Log.d(TAG, "onBlockQuoteFound: ${it.data} ${it.text}")
        } else if (it is FigureElement) {
            Log.d(TAG, "onFigure: ${it.caption}  ${it.url}")
        }
     } 
     } override fun onParseError(exception: Exception) {}})
       .build()
    

    现在我可以处理任何我想要的元素,例如:RecycleView

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多