Android Question Max Text Size

Discussion in 'Android Questions' started by RandomCoder, May 26, 2015.

  1. RandomCoder

    RandomCoder Well-Known Member Licensed User

    Had to go to bed not getting this to work and what's wrong is still evading me this morning :mad:

    Basically I would like to set the largest text size possible for Labels and Textbox's. But the views are not created in the designer and so I cannot let the designer and AutoScale take care of it. I've seen an example using StringUtils but was hoping to do this with just core functions. It dawned on me that the problem might be to do with padding around the text and for this I've used JavaObject.
    This fixed getting the text to display correctly in portrait mode but it is still too large when in landscape. It seems that if the height of the view is larger than the width then it works correctly but if smaller then the textsize is too large even though the canvas MeasureStringHeight suggests that it should fit?
    I've thrown together a small sample (attached), and the code I'm using is shown below.

    Private Sub maxTextSize(v As View, str As StringAs Float
    ' Get padding values
        Dim jo As JavaObject = v
    Dim intPaddingLR As Int= jo.Runmethod("getPaddingLeft",Null) + jo.Runmethod("getPaddingRight",Null)
    Dim intPaddingTB As Int = jo.Runmethod("getPaddingTop",Null) + jo.Runmethod("getPaddingBottom",Null)
    ' Set canvas and initialise text size to try
        Dim c As Canvas
    Dim fltSize As Float = 70
    Dim fltW As Float = c.MeasureStringWidth(str, Typeface.DEFAULT_BOLD, fltSize)
    Dim fltH As Float = c.MeasureStringHeight(str, Typeface.DEFAULT_BOLD, fltSize)
    ' Check if text size will fit, continue reducing until it fits.
        Do While (fltW > (v.Width - intPaddingLR)) OR (fltH > (v.Height - intPaddingTB))
            fltSize = fltSize - 
            fltW = c.MeasureStringWidth(str, 
    Typeface.DEFAULT_BOLD, fltSize)
            fltH = c.MeasureStringHeight(str, 
    Typeface.DEFAULT_BOLD, fltSize)
    Log(fltW & " (" & (v.Width - intPaddingLR) & ") " & fltH & " (" & (v.Height - intPaddingTB) & ")")
    Log("Size " & fltSize)
    Return fltSize
    End Sub

    Attached Files:

  2. Erel

    Erel Administrator Staff Member Licensed User

  3. RandomCoder

    RandomCoder Well-Known Member Licensed User

    I've placed several more log statements in the code and I believe that this line is the root cause of my problem...
    c.MeasureStringHeight(str, Typeface.DEFAULT_BOLD, fltSize)
    It is giving back the wrong value for the actual string height, as the canvas size and the padding values seem to be reporting they're size correctly when checked against the Label and Textbox height.

    I was hoping not to have to use Reflection and StringUtils as I'm creating a class which I'm trying to keep small in size, if the canvas will do all that I need then this is the preferred option for me. Is it possible that MeasureStringHeight is giving back the wrong value?
    ArminKH likes this.
  4. Cableguy

    Cableguy Expert Licensed User

    You need to take into account the device scale, and divide the measured value by it. You are measuring pixels, while the font size is measured in DPI I think... You can check in my "set text size" sub's in the on going project
  5. RandomCoder

    RandomCoder Well-Known Member Licensed User

    I'm not sure that is the problem as it works perfect when the view is higher than it is wide. I've found that if I multiply the measured string height by 1.75 it then works. I might just leave it like that.
  6. RandomCoder

    RandomCoder Well-Known Member Licensed User

    I'll try and test on some other devices to see if I can use a fixed multiplier or if I need to take into account the device scale!
  7. Cableguy

    Cableguy Expert Licensed User

    I use a fixed multiplier, and haven't had any issues until now...
  8. ivanomonti

    ivanomonti Well-Known Member Licensed User

    the result is quite good , I had to change to the bottom subtracting 4dip , just for a app that loads data like mine , the process becomes long , despite having a good level of device ( lg - flex )

  9. RandomCoder

    RandomCoder Well-Known Member Licensed User

    Try changing the starting value from 70 to a value closer to what you expect to need, then it won't loop as many times to find the largest text size.
    Dim fltSize As Float = 70
    I've also had to modify the MeasureStringHeight lines by multiplying the value by 1.75 to ensure it fits the text if the view is wider than it is tall...
    From this...
    As Float = c.MeasureStringHeight(str, Typeface.DEFAULT_BOLD, fltSize)

    To this...
    As Float = c.MeasureStringHeight(str, Typeface.DEFAULT_BOLD, fltSize)*1.75
  10. Cableguy

    Cableguy Expert Licensed User

    Do you get any values out of the "getPadding" methods? I basically copied a couple of lines from your example to get the padding but I'm always getting zero!
    My idea to get it perfect is to measure a fixed String like "tgjB" and then subtract the padding and divide the result by the density factor... But my font size is always a bit too big because the padding value is incorrect.
  11. RandomCoder

    RandomCoder Well-Known Member Licensed User

    The padding on Labels is normally zero, whereas the padding on a Textbox seems to be fixed at 48 horizontal (24 left and right) and 30 vertical (15 top and bottom).
    I've just run a quick test and it seems that these padding values are fixed irrespective of the size of the Textbox.
    Cableguy likes this.
  12. klaus

    klaus Expert Licensed User

    Your problem, needing a factor of 1.75 to get the correct TextSize, looks strange to me.
    I made some tests and cannot reproduce the problem.
    Could you send me some layout paramers showing the problem.
  13. RandomCoder

    RandomCoder Well-Known Member Licensed User

    Hi @klaus there are no layout parameters. The point I was trying to make was that I was creating the views in code not the designer (see post #1). If the view is wider than it is tall then all works correctly using Canvas.MeasureStringWidth but if the view is taller than it is wide then the text is sized incorrectly because Canvas.MeasureStringHeight is incorrectly reporting the expected height of the text. At least that is my feeble understanding of the problem. Erel has explained to me that in this case the correct method is to use StringUtils and Reflection libs as this uses a slightly different approach based on a higher api.
    It's now 02:30 in the morning and I've had several beers after attending a wedding reception so I'm going that all makes sense :D
    Cableguy and Roger Daley like this.