Android Question Resize Label text with Java Object

Roger Daley

Well-Known Member
Licensed User
Hi All,

On the question of scaling text between devices.

I have Klaus's code snippet for finding the best text size and works well. As all views use the same size font I use this code to find the text size for label1 and use it to set the text size of the other views.

I also use code [posted by either Erel or Klaus] to set the padding of views. This code uses Java Objects in a loop, I would like to use something similar to set the text size rather than the long list I am currently using.

The code below is what I am aiming for but can't find information on the "MethodName" or "Parameters" required.


B4X:
        ' Set padding on all views to zero.  
    For Each v As View In Activity.GetAllViewsRecursive
        If v Is Button Then
             Dim jo As JavaObject = v
             jo.RunMethod("setPadding", Array As Object(0, 0, 0, 0))
        End If
       If v Is EditText Then
             Dim jo As JavaObject = v
             jo.RunMethod("setPadding", Array As Object(0, 0, 0, 0))
       End If
       If v Is Label Then
             Dim jo As JavaObject = v
             jo.RunMethod("setPadding", Array As Object(0, 0, 0, 0))
       End If
    Next

'Klaus's code snippet
SetTextSize(Label1, "Label1 Text")

' Set  text size to Label1.textsize.  
    For Each v As View In Activity.GetAllViewsRecursive
        If v Is Button Then
             Dim jo As JavaObject = v
             jo.RunMethod("MethodName",Parameters)
        End If
       If v Is EditText Then
             Dim jo As JavaObject = v
             jo.RunMethod("MethodName",Parameters)
       End If
       If v Is Label Then
             Dim jo As JavaObject = v
            jo.RunMethod("MethodName",Parameters)
       End If
    Next

Any guidance greatfully appreciated.

Regards Roger
 

klaus

Expert
Licensed User
Try this code:
B4X:
If (v Is Button) Or (v Is EditText) Or (v Is Label) Then
    Dim jo As JavaObject = v
    jo.RunMethod("setTextSize", Array As Object(Label1.TextSize))
End If
Not sue if the () are necessary in the If statement.

This should work too:
B4X:
If v Is Label Then
    Dim jo As JavaObject = v
    jo.RunMethod("setTextSize", Array As Object(Label1.TextSize))
End If
If I remember well, EditTexts and Buttons are also considered as Labels (TextViews).
 

Roger Daley

Well-Known Member
Licensed User
Thanks thedesolatesoul and Klaus,

All tried and result below, all Labels, Edittexts and Buttons done in one hit.

B4X:
    SetTextSize(lblOffset, "LANDMARK OFFSET")
   
    For Each v As View In Activity.GetAllViewsRecursive
        If v Is Label Then
            Dim jo As JavaObject = v
            jo.RunMethod("setTextSize", Array As Object(lblOffset.TextSize))
        End If
    Next
Regards Roger
 

Roger Daley

Well-Known Member
Licensed User
Just to round out the thread, below is the final code. It adjusts text size with out java.
I found that using stringutils gave me a smaller than required text. I think that stringutils allows for the default padding, I have removed the padding to allow a larger text size. As an alternative to stringutils I have used Canvas.MeasureStringHeight, found I needed to use a 0.7 factor to get the correct sizing. I don't know why but it seems to work on different devices.

B4X:
Sub SetTextSize(lbl As Label, txt As String)
    Dim DeltaTextSize, TextSizeNow, TextSizeScale  As Float
    Dim limit = 0.5 As Float
    Dim TextHeight As Int
    Dim Canvas1 As Canvas
    Canvas1.Initialize(Activity)

    TextSizeNow = lbl.TextSize
    lbl.Text = txt
    lbl.TextSize = 76
    DeltaTextSize = 76    
   
    'Calculate correct text size for lbl [Sucessive approximation]
    TextHeight = Canvas1.MeasureStringHeight(txt, Typeface.DEFAULT, lbl.TextSize)
    Do While DeltaTextSize > limit OR TextHeight > (lbl.Height * 0.7)    '0.7 arrived at by trial and error
        DeltaTextSize = DeltaTextSize / 2
        TextHeight = Canvas1.MeasureStringHeight(txt, Typeface.DEFAULT, lbl.TextSize)
        If TextHeight > (lbl.Height * 0.7) Then                '0.7 arrived at by trial and error
          lbl.TextSize = lbl.TextSize - DeltaTextSize
        Else
          lbl.TextSize = lbl.TextSize + DeltaTextSize
        End If
    Loop
    TextSizeScale = lbl.TextSize/TextSizeNow    'Ratio between starting and ending text size for lbl
    lbl.TextSize = TextSizeNow        'Restore lbl text size before applying text scale factor to all views

    For Each v As View In Activity.GetAllViewsRecursive  'Adjust all textviews by TextSizeScale
        If v Is Label Then
            Dim lbl As Label = v
            lbl.TextSize = lbl.TextSize * TextSizeScale
        End If
    Next

End Sub




I hope this makes sense and is usefull. Thanks for all the help and let me know if you find a problem.

Regards Roger
 
Last edited:

klaus

Expert
Licensed User
Unfortunately your code will not work in all cases because Canvas1.MeasureStringHeight returns different values depending on the text.
Example:
Canvas1.MeasureStringHeight("a", Typeface.DEFAULT, 16)
Canvas1.MeasureStringHeight("A", Typeface.DEFAULT, 16)
Canvas1.MeasureStringHeight("Aj", Typeface.DEFAULT, 16)
These three statements return different values !
The factor of 0.7 is probably due to the padding and perhaps the fact above.
I am also not convinced that it will work for all cases. The padding in a Label is constant independant of the TextSize.
 

Roger Daley

Well-Known Member
Licensed User
Klaus

You are probably correct, I had a gut feeling someone would find holes in it. Fortunately it appears to be working in this project.
I don't think padding is an issue here as the padding should be zero.

B4X:
        ' Set padding on all views to zero.   
    For Each v As View In Activity.GetAllViewsRecursive
       If v Is Label Then
             Dim jo As JavaObject = v
             jo.RunMethod("setPadding", Array As Object(0, 0, 0, 0))
       End If
    Next
   
    SetTextSize(lblOffset, "LANDMARK OFFSET")
Possibly in other cases the developer would need to find a factor other than 0.7 by trial and error for their specific application.
Preferably stringutils would factor the actual padding of each view.
In an instance produced using stringutils, I checked the sizes. Label.textsize = 26, the Label.height = 50. This is a considerable percentage of the label real estate not used.

I guess the real problem is me trying to get bigger text in to a label. :)

Thanks again for the feedback
Roger
 
Top