Android Question [Solved by Klaus] 9 patch height

Discussion in 'Android Questions' started by LucaMs, Jun 13, 2019.

  1. LucaMs

    LucaMs Expert Licensed User

    I ran tests on some 9 patches I made and also using one found here on site (the one in the attached project) but in all my tests the height of the view is wrong.

    Where am I wrong?

    Attached Files:

    Last edited: Jun 13, 2019
  2. LucaMs

    LucaMs Expert Licensed User

    Found right now this one on web... it works worse, although in the tool it looks ok.

  3. Erel

    Erel Administrator Staff Member Licensed User

    You can draw it yourself:


    Tested in B4J:
    Sub Process_Globals
    Private MainForm As Form
    Private ImageView1 As ImageView
    Private xui As XUI
    Private ImageView2 As ImageView
    Private ImageView3 As ImageView
    End Sub

    Sub AppStart (Form1 As Form, Args() As String)
       MainForm = Form1
    "1"'Load the layout file.
    End Sub

    Sub CreateComicBalloon (ImageView As B4XView)
    Dim bcGradient As BitmapCreator
    ImageView.Width / xui.Scale, ImageView.Height / xui.Scale)
    Array As Int(xui.Color_White, 0xFFCACACA), bcGradient.TargetRect, "TOP_BOTTOM")
    Dim bc As BitmapCreator
       bc.Initialize(bcGradient.mWidth, bcGradient.mHeight)
    Dim brush As BCBrush = bc.CreateBrushFromBitmapCreator(bcGradient)
    Dim borderBrush As BCBrush = bc.CreateBrushFromColor(xui.Color_Black)
    Dim r As B4XRect
    00, bc.mWidth, bc.mHeight * 0.8)
       bc.DrawRectRounded2(r, brush, 
       bc.DrawRectRounded2(r, borderBrush, 
    Dim path As BCPath
    Dim len As Int = (bc.mHeight - r.Bottom) / 3
    path.Initialize(60, r.Bottom-2)
    path.LineTo(60 + len, bc.mHeight)
    path.LineTo(60 + 2 * len, r.Bottom-2)
    path, brush, True0)
    path, borderBrush, False1)
    End Sub
    If you are creating many balloons then it is better to create the two BCs once with the maximum size and reuse them.
  4. LucaMs

    LucaMs Expert Licensed User

    Thank you, Erel, but the question is different (my damned english :D): the label to wich I set the 9patch as background does not resize itself correctly basing on the content (its height is always wrong).

    You can see this running the test project attached to the first post.
  5. LucaMs

    LucaMs Expert Licensed User

    I have to know whether I'm badly managing the 9patches or if I draw them wrong (but also the ones I found - it's not important that they are balloons - they don't give the expected results) or what else.

    [However, there is a small bug in your routine, Erel (and if anyone wanted to use it...)]

  6. Peter Simpson

    Peter Simpson Expert Licensed User

    I would say your 1st speech bubble is way too small. In any case Erel's code is simple enough to adjust, you can move the bottom 'V' over yourself silly.

    Oh btw creating a 9 Patch image is extremely simple, I created a post or two on here a long time ago about 9 Patch. Your best bet is to watch a couple of YouTube videos about 9 Patch and learn from them.
    DonManfred and Erel like this.
  7. LucaMs

    LucaMs Expert Licensed User

    I have posted that bubble/balloon in the 2nd post just to say that I tried also that 9patch image found on Internet and this one too does not "work" as I expected, just to say that the problem does not seem how I create 9patch images. I might want to display text in a very different form than that.

    Please, run the test project, if you want to understand what I mean (in it, as I said, I tried a 9patch image
    found on b4x, exactly here:
    and even that class does not show texts correctly, because of the same reason: the height will be not automatically set well).

    Thank you.
  8. LucaMs

    LucaMs Expert Licensed User

    I don't know what the reason is, maybe I don't know how to use it, but the images "created" with the google tool (old tool, currently you can use it only from within Android Studio, which I really don't like) don't give the desired results, while those generated by this online tool do.
  9. Peter Simpson

    Peter Simpson Expert Licensed User

    It works 100%, your doing it incorrectly. Even in my challenge 2 video on the forum I use a 9 Patch image with the photos to show the item stock images (bottom right corner line), actually most of my apps I use 9 Patch with absolutely no issues whatsoever.

    I tell you what your problem is, when something is not as you expect it you ALWAYS blame the tools and never the developer (YOU), it's becoming extremely tiresome. I've watched you over the years say that things don't works as you expected when they clearly do most of the time, it's the developer, don't you get it. I clearly remembered when you ranted, raved and moaned profusely about the designer, designer script and anchors on multiple occasions claiming there were big issues and that things are not good with it, everything is incorrect and you are correct (in your mind), you just can't help yourself. Take a long look at yourself and learn a few things.

    Well @LucaMs I'm telling you that YOU are doing it incorrectly.

    Welcome to my ignore list, done...
    Last edited: Jun 17, 2019
    DonManfred likes this.
  10. LucaMs

    LucaMs Expert Licensed User


    But with that site I can create and use the 9 patches :eek:
  11. LucaMs

    LucaMs Expert Licensed User

    (Post #1)
    (Post #8)

    Can you, Peter (*) (or DonManfred, Erel or anyone else) try this simple test project, please?

    Note that:

    1) when you click on "Show" the first time, the label (with 9 patch as background) will be N high (and wrong), the second time it will be N*M (and still wrong), this despite the very simple code;
    2) I use StringUtils.MeasureMultilineTextHeight to resize the label and this is why I show a second blue label, to check its result (and it is correct);
    3) this is how the 9 patch looks in the Google's tool:

    Is my 9png wrong? Ok, change it with your own.

    Finally, I don't think the initial size of the label matters, since MeasureMultilineTextHeight will be applied to it and because the background will be set to the 9 patch image; so, please, do not change its size.

    Thank you.

    P.S. this is how the project looks:

    (*) P.P.S. I hadn't seen this:
    and I don't understand why but it's ok.

    Attached Files:

    Last edited: Jun 18, 2019
  12. klaus

    klaus Expert Licensed User

    When done correctly it works OK.


    The problem is the Padding!
    su.MeasureMultilineTextHeight(Lbl, Text) doesn't take into account the Padding.
    Therefore you must first get the padding values and then define a new label without the padding, measure the height and add the top and bottom padding values to the height.
    And another point:
    You adjust the height before adding the 9patch image. This means that the padding is not yet known!

    Attached a modified version of your project.

    The Adjustment routine:
    Sub AdjustLabelHeight(Lbl As Label, Text As String ,TextSize As Float)
    Private jolbl As JavaObject
    Private pl, pt, pr, pb As Int
        jolbl = Lbl
        pl = jolbl.RunMethod(
        pt = jolbl.RunMethod(
        pr = jolbl.RunMethod(
        pb = jolbl.RunMethod(
    Private lblDummy As Label
    Activity.AddView(lblDummy, 00, Lbl.Width - pl - pr, Lbl.Height - pt - pb)
        lblDummy.Text = Text
        lblDummy.TextSize = TextSize
        Lbl.Text = Text
        Lbl.TextSize = TextSize
    Dim su As StringUtils
        Lbl.Height = su.MeasureMultilineTextHeight(lblDummy, Text) + pt + pb
    End Sub
    EDIT: 2019.06.19
    The same routine using the Padding property instead of a JavaObject.
    Sub AdjustLabelHeight(Lbl As Label, Text As String ,TextSize As Float)
    Private pd(4As Int 
        pd = Lbl.Padding 
    Private lblDummy As Label
    Activity.AddView(lblDummy, 00, Lbl.Width - pd(0) - pd(2), Lbl.Height - pd(1) - pd(3))
        lblDummy.Text = Text
        lblDummy.TextSize = TextSize
        Lbl.Text = Text
        Lbl.TextSize = TextSize
    Dim su As StringUtils
        Lbl.Height = su.MeasureMultilineTextHeight(lblDummy, Text) + pd(
    1) + pd(3)
    End Sub

    Attached Files:

    Last edited: Jun 19, 2019
  13. LucaMs

    LucaMs Expert Licensed User

    First of all, thank you Klaus for having tried and solved the problem (you're always willing to help, great Klaus).

    I had thought to Padding but I knew (or thought I knew) that it was fixed for each type of View and that it didn't depend on the content.
    Thinking this, I did a log of the padding of an empty label, without text, and the log showed all zeros. I had also did the same test on a Button and an EditText and these have different default values.
    Imagine that it is only in this way, at @LordZenzo's suggestion, that I discovered that "now" the views have the Padding property while I had used one of your precious snippets.

    However it was as I thought, the padding is fixed; it changes just with the application of the 9Patch which, as you rightly observed, must be done before changing the text, in this case before using the MeasureMultilineTextHeight.

    I renew my thanks to you, Klaus, for having tried, for having solved, for explaining and also for having taken seriously my request while others ignored it and someone had only the bad idea to offend (some petty person whom sooner or later life will give him what he deserves; but it has probably already been done).
    Last edited: Jun 18, 2019
  14. sorex

    sorex Expert Licensed User

    padding can be changed since Android 2.2 or even earlier.

    the problem is with IOS where you need to do some other trickery if you want centered text look exactly the same as on Android.
    (padding, kerning behaves strange there)
  15. Erel

    Erel Administrator Staff Member Licensed User

    I agree with this statement.

    I don't agree. Other members have tried to help you. I created a full example based on a different approach just to help you solve your problem. Even if it was not useful for you it doesn't mean that I haven't invested quite a lot of time in writing this code (post #3).

    If I were to implement such solution I would have chosen the drawing approach as it is more flexible. Adding the text should be simple.
  16. LucaMs

    LucaMs Expert Licensed User

    I know that you, Erel, have spent time developing that useful routine that I appreciate and also I want to study it (I want to study everything about CreateBitmap) and thank you again but what I wanted to understand was if I had a wrong idea about how 9patches work or if I used them badly. The only member who downloaded one of the two projects I attached was Klaus.

    Someone may have thought that I was criticizing the 9patches (re-reading Klaus's post, perhaps even himself, given the first line he wrote).
  17. LucaMs

    LucaMs Expert Licensed User

    A slightly modified version.
    ' Returns the number of text lines.
    Sub AdjustLabelHeight(Lbl As LabelAs Int
    Dim lblDummy As Label
    Dim Parent As Panel = Lbl.Parent
    00, Lbl.Width - Lbl.Padding(0) - Lbl.Padding(2), Lbl.Height - Lbl.Padding(1) - Lbl.Padding(3))
        lblDummy.Text = Lbl.Text
        lblDummy.TextSize = Lbl.TextSize
        lblDummy.Typeface = Lbl.Typeface
    Dim su As StringUtils
        Lbl.Height = su.MeasureMultilineTextHeight(lblDummy, Lbl.Text) + Lbl.Padding(
    1) + Lbl.Padding(3)

    Dim Source As JavaObject = Lbl
    Dim LineCount As Int = Source.RunMethod("getLineCount"Null) + 1
    Return LineCount
    End Sub
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice