Italian Sub SetLabelSize(lbl As Label, txt As String) Spiegazione

LucaMs

Expert
Licensed User
Longtime User
Ma senza inizializzazione su quale view "disegna"? Boh, scarico il tuo esempio.
1609101112721.png


Possibile che il motivo (per il quale funziona malgrado non sia inizializzato) sia perché è B4J?
 

Star-Dust

Expert
Licensed User
Longtime User
Prova questo (non esattamente B4X, andrebbe adattato, ma con B4A funziona)
Il tuo progetto calcola solo l'altezza lui vuole anche che rientri in larghezza.
 

LucaMs

Expert
Licensed User
Longtime User
Il mio progetto è "strano" (usa una ScrollView, come hai visto).
Credo sia meglio così, senza cambiare TextSize che, come già scritto sia da te che da me, potrebbe risultato troppo piccolo (o magari troppo grande).

Una "Label scrollabile verticalmente", in quel modo, penso sia la soluzione migliore.
 

Star-Dust

Expert
Licensed User
Longtime User
Il mio progetto è "strano" (usa una ScrollView, come hai visto).
Credo sia meglio così, senza cambiare TextSize che, come già scritto sia da te che da me, potrebbe risultato troppo piccolo (o magari troppo grande).

Una "Label scrollabile verticalmente", in quel modo, penso sia la soluzione migliore.
Per un link, magari non renderebbe più chiaro visualizzandolo in più righe... e comunque non serve StringUtil per misurare il testo in una scrollview.
 

Star-Dust

Expert
Licensed User
Longtime User
Come detto, il progetto allegato non è adattato per B4X; se vuoi farlo, senza usare StringUtils...!
StringUtil misura solo l'altezza. Con B4xCanvas misuri anche la larghezza di un testo.

È a lui serve la larghezza
 

GIS

Well-Known Member
Licensed User
B4X:
Sub SetLabelSize(lbl As B4XView, txt As String)
    Dim dt=72 As Float
    Dim limit = 0.1 As Float
    Dim MaxW As Double  = lbl.Width * 0.9
    Dim MaxH As Double  = lbl.Height * 0.9
    Dim Can As B4XCanvas 'ignore
    Dim Rec As B4XRect = Can.MeasureText(txt,xui.CreateDefaultFont(lbl.TextSize)) ' va in crash su questa linea in B4A

    lbl.Text = txt
    lbl.TextSize = dt
    Log("-")
    Do While (dt > limit) Or (Rec.Height > MaxH) Or (Rec.Width>MaxW)
        dt = dt / 2
        Dim Rec As B4XRect = Can.MeasureText(txt,xui.CreateDefaultFont(lbl.TextSize))
        If (Rec.Height > MaxH) Or (Rec.Width>MaxW) Then       
            lbl.TextSize = lbl.TextSize - dt
        Else
            lbl.TextSize = lbl.TextSize + dt
        End If
    Loop
End Sub
 

Star-Dust

Expert
Licensed User
Longtime User
Quanto ho capito non è per B4A, giusto?
Ti ho allegato il progetto funzionante e testato per b4j nel post #42
Nella finestra del codice ho fatto una piccola modifica che inizializza B4XCanvas (Serve solo B4A e B4i) e diventa multipiattaforma
 
Last edited:

GIS

Well-Known Member
Licensed User
Ti ho allegato il progetto funzionante e testato per b4j nel post #42
ok, grazie. Sono arrivato a casa adesso dalle 5 di stamattina, giornata assurda con la neve. Lo sapevano da giorni che nevicava ma è stato un disastro!!! Cmq più tardi ci guardo
 

Star-Dust

Expert
Licensed User
Longtime User
il risultato è corretto. Come previsto è piccolissimo.

Considerando che hai messo un immagine di background dovevi ridurre i margini al 80% è non solo al 90 per far rientrare il testo all'interno dell'immagine scelta.
Ma sarebbe ancora più piccolo
 

GIS

Well-Known Member
Licensed User
La cosa che non capisco, è perchè la label la fa cosi piccola in larghezza. Io nel designer lo allargata a tutto schermo
 

Star-Dust

Expert
Licensed User
Longtime User
Fammi un piccolo esempio solo con questa label cosi la guardo. Ma non avevi detto B4J?

A me sembra B4A.
 

Star-Dust

Expert
Licensed User
Longtime User
Hai risposto a questo mio:

Non so, ma @Star-Dust ha scritto che Erel non aveva inizializzato un B4XCanvas e non so lui a quale esempio di Erel si riferisse.
Per usare MeasureText non è necessario inizializzare la tela, è come un metodo di tipo final che non va creato l'istanza. In ogni caso in B4J la Canvas è già un oggetto a se e non deve essere legato a una View o una bitmap come invece succede in B4A o B4i
 
D

Deleted member 103

Guest
B4X:
Sub SetLabelSize(lbl As Label, txt As String)
    Dim dt As Float
    Dim limit = 0.1 As Float
    Dim h As Int

    lbl.Text = txt
    lbl.TextSize = 72
    dt = lbl.TextSize
    h = stu.MeasureMultilineTextHeight(lbl, txt)
    Do While dt > limit Or h > lbl.Height
        dt = dt / 2
        h = stu.MeasureMultilineTextHeight(lbl, txt)
        If h > lbl.Height Then
            lbl.TextSize = lbl.TextSize - dt
            lbl.TextSize = lbl.TextSize - 1 'ho aggiunto questo meno 1 se no a volte la scritta era grande e non si leggeva
        Else
            lbl.TextSize = lbl.TextSize + dt
            lbl.TextSize = lbl.TextSize - 1 'ho aggiunto questo meno 1 se no a volte la scritta era grande e non si leggeva
        End If
    Loop

Ciao è da molto che uso questa sub insieme alla gemella per centrare le parole nei vari button o label. Ma ha volte non fa quello che mi aspetterei. Vorrei modificarla ma non capisco bene il valore delle variabili. es.
lbl.Height misura dell'altezza che su una riga è 87. Ma 87 di cosa, pixel?
lbl.TextSize = 72 qui viene assegnato la grandezza del carattere, credo
h calcola l'altezza nel caso ci siamo più linee

Ho dove posso trovare il manuale di questa libreria che non riesco a trovare? O ferse c'è un modo migliore per fare questa operazione. Dimenticavo la libreria StingUtils. Ho provato a guardare la libreria ma io non ci ho trovato niente che mi dava spiegazioni. Il problema io l'ho sulla lunghezza forse questa sub non serve al mio scopo o sbaglio?
Prova questa classe, l'ho svilupata io e la uso in tutti i miei progetti.
B4X:
Sub Class_Globals
    Private bmp As Bitmap
    Private cvs As Canvas

    Private stu As StringUtils
    Private dt As Float
    Private h, Height As Int
    Private w, Width As Int
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    bmp.InitializeMutable(2, 2) 'ignore
    cvs.Initialize2(bmp)
End Sub

#Region TextSize vom Label, EditText und Button ändern

The "Scale" parameter is not used for buttons!
Public Sub SetTextSize(obj As View, txt As String, scale As Float, singleline As Boolean)
    'Log("SetTextSize: txt=" & txt & " :obj=" & obj)

    'WICHTIG! Object muss initialisiert sein!
    If Not(obj.IsInitialized) Then Return

    'WICHTIG! Die Width darf nicht weniger als 30dip sein!
    If obj.Width < 30dip Then Return

'    Dim p() As Int = obj.Padding
'    Log((p(0) + p(2)) / GetDeviceLayoutValues.Scale) '23dip
'    Log("obj.Height=" & obj.Height)
   
    setSingleLine(obj, singleline)

    If obj Is Button Then
        Dim btn As Button = obj
        Height = btn.Height - 14dip
        Width = btn.Width - 10dip

        SetButtonTextSize(btn, txt)
    Else
        Dim lbl As Label = obj
        Height = lbl.Height * scale
        Width = lbl.Width - 5dip
       
        SetLabelTextSize(lbl, txt)
    End If
End Sub

'Sets the TextView to single line
Public Sub setSingleLine(TextView As View, SingleLine As Boolean)
    Dim jo = TextView As JavaObject
    jo.RunMethod("setSingleLine", Array As Object(SingleLine))
End Sub

Private Sub SetButtonTextSize(btn As Button, txt As String)  
    btn.TextSize = 6
    dt = btn.TextSize
    h = stu.MeasureMultilineTextHeight(btn, txt)
    w = cvs.MeasureStringWidth(txt, btn.Typeface, dt)
    Do While h <= Height
        dt = dt + 1
        btn.TextSize = dt
        h = stu.MeasureMultilineTextHeight(btn, txt)
        w = cvs.MeasureStringWidth(txt, btn.Typeface, dt)
       
        If w >= Width Or h > Height Then
            btn.TextSize = dt - 2
            Exit
        End If
    Loop
End Sub

Private Sub SetLabelTextSize(lbl As Label, txt As String)
    Dim s() As String = Regex.Split(CRLF, txt)
    Dim NewTxt As String = txt
    If s.Length > 1 Then
        Dim l As Int
        For i = 0 To s.Length - 1
            If l < s(i).Length Then
                l = s(i).Length
                NewTxt = s(i)
            End If
        Next
    End If

    lbl.TextSize = 6
    dt = lbl.TextSize
    h = stu.MeasureMultilineTextHeight(lbl, txt)
    w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)
    Do While h <= Height
        dt = dt + 1
        lbl.TextSize = dt
        h = stu.MeasureMultilineTextHeight(lbl, txt)
        w = cvs.MeasureStringWidth(NewTxt, lbl.Typeface, dt)

'        Log(txt & ": w=" & w & " ;h=" & h)
'        Log(txt & ": Width=" & Width & " ;Height=" & Height)
   
        If w > Width Or h > Height Then
            lbl.TextSize = dt - 1
            Exit
        End If
    Loop
End Sub
#End Region
 

GIS

Well-Known Member
Licensed User
Prova questa classe, l'ho svilupata io e la uso in tutti i miei progetti.
ok. Mi devi spiegare cosa devo fare perchè non sono pratico di classi. Devo creare un modulo Class Standard? Ma tutto il codice va nella class?
 
Top