Spannable text that holding custom view

740 views Asked by At

Is that possible to add a custom view into a spannable text?

In android.text.style package I can see many types of spannable objects, but I wonder if I can add a custom view.

Sort of spanable.setSpan(CustomView, .. , .. ,..)

Note that: CustomView maybe any sort of view i.e: WebView

2

There are 2 answers

0
Ibrahim Ali On BEST ANSWER

So looks like it will be challenging to use Spannable way to handle such case.

Therefore I created a new library to handle tags so I can use them wherever I want.

And here is an example

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()

Now I can handle elements in whatever I want i.e: RecycleView

0
wonsuc On

In Android, only ViewGroup class can contain another view, therefore it's much proper to say,

Is that possible to add a spannable text into a custom view?

Then the answer is Yes, if your custom view extends ViewGroup class.

However, if you want to draw specific graphics or animations with spannable, you would need to draw on the Canvas directly from your custom view.

For examples, if you check DynamicDrawableSpan class in android.text.style package.

@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();
}

It has draw method which draw the Drawable on the Canvas directly, this code will be good start if you want to create custom spannable class which displays various things more than existing SDK classes.