8

I'm writing a custom layout that will manage text. Before I started implementing the ViewGroup#onMeasure() method I started to dig the EditText source code, specifically at the EditText#onMeasure() method. So I came across the BoringLayout. I read the docs but I didn't find much explanation on it and how to use it in an actual custom implementation. Then my question is how can I use it the right way and when it is really needed.

kaneda
  • 5,981
  • 8
  • 48
  • 73
  • Hi, could you be a little more specific? BoringLayout is not really meant to manage text. What do you mean when you say "manage text?" A little more detail about what your app should do will help greatly, code samples are even better. – Otra Nov 06 '12 at 16:28
  • @Otra I meant my layout will be managing text according to text width of some component. `BoringLayout` would help me achieve that by giving me the metrics of the text. I want to know how it can be applied correctly. – kaneda Nov 06 '12 at 18:38
  • 1
    You may no need an entire layout for that. See if this answer helps any: http://stackoverflow.com/questions/3630086/how-to-get-string-width-on-android – Otra Nov 07 '12 at 12:29
  • I'm trying to investigate BoringLayout as since I've read on the Android documentation the next: You should not need to use this class directly unless you are implementing your own widget or custom display object, in which case you are encouraged to use a Layout instead of calling Canvas.drawText() directly. I've always used Canvas.drawText(), I'm doing this wrong? – Sotti Oct 19 '14 at 13:05
  • 1
    wrong is relative, nothing prevents you from drawing yourself on the canvas but BoringLayout is here to help you in that task. All the framework widgets I know of use it instead of drawing directly on the canvas. The documentation of this class is very lacking though. – Teovald May 21 '15 at 16:03

2 Answers2

17

BoringLayout is used to draw text on a view. It is called "boring" because it only handles a single line of left-to-right text without any interesting characters such as emoji. This simplification allows the class to override onDraw with more efficient logic than the default does. Here is the source code if you want to see for yourself.

Like StaticLayout and DynamicLayout, the BoringLayout is also a subclass of the abstract Layout class. As the documentation says, you probably wouldn't use these classes directly unless you are making your own text handling widget. How do you know if you should be using one of these classes? If you are thinking about using Canvas.drawText in your custom view, then you should probably think about using a Layout. They also eventually call Canvas.drawText, but they do a lot of other processing beforehand.

If you are making your own text widget, then you would only use the BoringLayout for single line, simple, left-to-right text. For multi-line and more complex text use a StaticLayout. And if you need to dynamically change the text after creation, then use a DynamicLayout.

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
1

Technically, you can draw text on the canvas with `canvas.drawText("text");
However, text is a very general term and can get extremely complicated : is it LeftToRight or RightToLeft ? is it Ellipsized ? is it single or multiLine ? ...

android.text.Layout is here to handle all this.

the typical way to use it is :

        BoringLayout.Metrics boring = BoringLayout.isBoring(mText, mPaint);
    if (boring != null) {
        // this is boring !
        if (mSavedLayout != null) {
            mLayout = mSavedLayout.replaceOrMake(mText,
                    mPaint,
                    availableWidth,
                    Layout.Alignment.ALIGN_NORMAL,
                    SPACING_MULT,
                    SPACING_ADD,
                    boring,
                    true,
                    TextUtils.TruncateAt.END,
                    availableWidth);
        } else {
            mLayout = BoringLayout.make(mText,
                    mPaint,
                    availableWidth,
                    Layout.Alignment.ALIGN_NORMAL,
                    SPACING_MULT,
                    SPACING_ADD,
                    boring,
                    true,
                    TextUtils.TruncateAt.END,
                    availableWidth);
        }
        mSavedLayout = (BoringLayout) mLayout;
    } else {
        mLayout = new StaticLayout(mText,
                0,
                mText.length(),
                mPaint,
                availableWidth,
                Layout.Alignment.ALIGN_NORMAL,
                SPACING_MULT,
                SPACING_ADD,
                true,
                TextUtils.TruncateAt.END,
                availableWidth);
    }
Teovald
  • 4,369
  • 4
  • 26
  • 45