German Draw 9 Patch Bilder

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Da musst Du erst erklähren was Du genau machen willst.
Du kannst die Breite einer Variablen zuweisen und diese benutzen.
B4X:
Dim Label1 As Label
Label1.Initialize("Label1")
Label1.Text = "Test"
Dim Breite As Int
Breite = 100dip
Panel1.AddView(Label1, ScrollView1.Width - Breite, 10dip, Breite, 50dip)
' ab hier ist Label1:Width gleich 100dip
Beste Grüsse.

Naja, ich habe eine Sprechblase, der dann den Text enthält.
Und der darf dann aber nicht in die Gesamte Breite gezogen werden, wenn es nur einen einzigen Wort enthält.
 

klaus

Expert
Licensed User
Longtime User
Oder, ich könnte doch die länge der Label1.Text = "Test" ermitteln und daraus mir eine Breite definieren?
Das ist möglich.
Dafür brauchst Du ein Canvas und mit Canvas.MeasureStringWidth(Text As String, Typeface As Typeface, TextSize As Float) kannst Du die Breite ermitteln musst aber die Links- und Rechtspatchbreiten mit hinzuzählen.
Dann musst Du aber testen ob die Textbreite grösser als die Scrollviewbreite ist und den kleineren Wert nehmen.

Beste Grüsse.
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hi Klaus,

was ist denn bitte hiermit gemeint?

B4X:
musst aber die Links- und Rechtspatchbreiten mit hinzuzählen.
 

klaus

Expert
Licensed User
Longtime User
Der Text kann nicht die volle Breite und Höhe ausnützen Du hast links und rechts genau wie oben und unten Ränder. Das sind die Links- und Rechtspatchwerte.
Schau in Post #14 da habe Ich mit der Reflection Library die oberen und unteren Patchwerte Ränder) ausgelesen.
Die kann mit
B4X:
r.RunMethod("getPaddingLeft")
r.RunMethod("getPaddingRight")
ermitteln.

Beste Grüsse.
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hallo Klaus,

ey man das ist garnicht so einfach.

Die Sprechblase soll eine Breite haben, wie lang der Text ist.
Aber es darf nicht die volle Breite des Scrollviews haben.

d.h. sollte der Text länger sein als die gesamte Scrollview Breite, dann soll
autom. eine Zeilenumbruch folgen.

Die Zeilenumbruch soll nach dreiviertel gesamt Breite sein.

kannst du mir ein Tipp geben :) ?

hier mein code :)
B4X:
Sub KarsidanGelenler(gelenmsg)
 Dim r As Reflector
  Dim lbl As Label
 Dim neuelaengetext As String
 
  Dim Breite As Float
  Dim Canvas1 As Canvas
Canvas1.Initialize(Activity)

        lbl.Initialize("Label")
      
      neuelaengetext = gelenmsg
      
      If gelenmsg.Length > 40 Then
      neuelaengetext = Left(gelenmsg,40)
        neuelaengetext = neuelaengetext & CRLF
      neuelaengetext = neuelaengetext & Mid(gelenmsg,41)
      
      Log(neuelaengetext)
      End If
      
      Breite = Canvas1.MeasureStringWidth(neuelaengetext, Typeface.DEFAULT, 14)

Log(Breite)
      
        ScrollView1.Panel.AddView(lbl, 0, TotalHeight, Breite + 30, 0)
      
      SetNinePatchDrawable(lbl, "karsidangelen")
      
    
        lbl.Tag = i
        lbl.TextColor = Colors.Black
        lbl.Text = gelenmsg

        ht = su.MeasureMultilineTextHeight(lbl, gelenmsg)
        r.Target = lbl

        ht = su.MeasureMultilineTextHeight(lbl, gelenmsg)
        
        ht = ht + r.RunMethod("getPaddingTop")
        ht = ht + r.RunMethod("getPaddingBottom")
        lbl.Height = ht
        TotalHeight = TotalHeight + ht
End Sub
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Klaus,

also das mit dem
B4X:
r.RunMethod("getPaddingLeft")
r.RunMethod("getPaddingRight")

habe ich auch nicht hinbekommen : -)
 

klaus

Expert
Licensed User
Longtime User
Du hast auch eine PM bekommen.

Ich habe es so gemacht:
B4X:
Sub Process_Globals
    Dim su As StringUtils

    Dim Index As Int
    Dim ht = 0 As Int

    Dim RaenderX, RaenderY  As Int
    Dim Spalte = 2dip As Int        ' Spalte zwischen den Labels
    Dim TotalHeight = Spalte As Int
End Sub

Sub Globals
    Dim ScrollView1 As ScrollView
    Dim Canvas1 As Canvas
End Sub

Sub Activity_Create(FirstTime As Boolean)
    Activity.LoadLayout("1")
    Canvas1.Initialize(Activity)
    
    ' Dieses Label wird nur erstellt um die Reander zu messen
    Dim lbl As Label
    lbl.Initialize("")
    Activity.AddView(lbl, 110%x, 0, 100dip, 50dip) ' Stelle ausserhalb des Bildschirms
    SetNinePatchDrawable(lbl, "karsidangelen")
    RaenderX = GetReanderX(lbl)
    RaenderY = GetReanderY(lbl)
    lbl.RemoveView    ' hier wird es wieder gelöscht
    
    AddRow("Links", "Kurzer Text")
    AddRow("Links", "Langer Text mit Zeilenumbruch mal schauen wie das aussieht" & CRLF & "und hier ist die Zeilenumbruch")
    AddRow("Links", "Die Sprechblasen sollten aber auch etwas luft zwischen den einzelnen Zeilen haben")
    AddRow("Rechts", "Langer Text ohne Zeilenumbruch um Text mal schauen wie das dargestellt wird. Werden auch Smilies dargestellt?")
    AddRow("Rechts", "Kurzer Text")
    AddRow("Rechts", "Und ich muss sorgar rechtsbündig darstehen :-)")
    
    ScrollView1.Panel.Height = 100%y 'TotalHeight 
End Sub

Sub AddRow(Wo As String, txt As String)
    Dim lbl As Label
  Dim Breite As Float
    lbl.Initialize("Label")
    
    Breite = Canvas1.MeasureStringWidth(txt, Typeface.DEFAULT, 14) + RaenderX
    Select Wo
    Case "Links"
        Breite = Min(Breite, 0.8 * ScrollView1.Width) ' Du kannst hier mit x * ScrollView1.Widthdie die maximale Breite bestimmen
        ScrollView1.Panel.AddView(lbl, 0, TotalHeight, Breite, 0)
        SetNinePatchDrawable(lbl, "karsidangelen")
        lbl.Gravity = Gravity.LEFT    ' nur zum schauen was möglich ist
    Case "Rechts"
        Breite = Min(Breite, 0.6 * ScrollView1.Width) ' Du kannst hier mit x * ScrollView1.Widthdie die maximale Breite bestimmen
        ScrollView1.Panel.AddView(lbl, ScrollView1.Width - Breite, TotalHeight, Breite, 0)
        SetNinePatchDrawable(lbl, "bendengelen")
        lbl.Gravity = Gravity.Right
    End Select

    lbl.Tag = Index
    lbl.TextColor = Colors.Black
    lbl.Text = txt

    ht = su.MeasureMultilineTextHeight(lbl, txt) + RaenderY

    lbl.Height = ht
    TotalHeight = TotalHeight + ht + Spalte
    Index = Index + 1

    ScrollView1.Panel.Height = TotalHeight
    DoEvents
End Sub

Sub Label_Click
    Dim lbl As Label
    
    lbl = Sender
    ToastMessageShow("Label " & lbl.Tag & " clicked", False)
End Sub

Sub SetNinePatchDrawable(Control As View, ImageName As String)
    Dim r As Reflector
    Dim package As String
    Dim id As Int
    package = r.GetStaticField("anywheresoftware.b4a.BA", "packageName")
    id = r.GetStaticField(package & ".R$drawable", ImageName)
    r.Target = r.GetContext
    r.Target = r.RunMethod("getResources")
    Control.Background = r.RunMethod2("getDrawable", id, "java.lang.int")
End Sub

Sub GetReanderX(v As View) As Int
    Dim refl As Reflector
    
    refl.Target = v
    Return (refl.RunMethod("getPaddingLeft") + refl.RunMethod("getPaddingRight"))
End Sub

Sub GetReanderY(v As View) As Int
    Dim refl As Reflector
    
    refl.Target = v
    Return (refl.RunMethod("getPaddingTop") + refl.RunMethod("getPaddingBottom"))
End Sub
Beste Grüsse.
 
Last edited:

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hallo Klaus,

danke erst mal für deine riesen große Hilfe.

Warum lässt sich der Scrollview nicht scrollen? :)
jedenfalls ist es bei mir der Fall.

Ich habe mal sehr viele Zeilen eingefügt um zu sehen was passiert aber der Scroller funktioniert nicht. Muss ich da vielleicht irgend etwas aktivieren?

gruß
sinan
 

klaus

Expert
Licensed User
Longtime User
Sorry, ja du hast Recht es fehlen zwei Zeilen am Ende der AddRow Routine:
B4X:
ScrollView1.Panel.Height = TotalHeight
DoEvents
Ich hatte es leider nur mit wenigen Einträgen probiert.
Habe den Code in Post#30 dementsprechend ergänzt.

Beste Grüsse.
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hallo Klaus,

mir ist gerade aufgefallen, das wir hier den ScrollView nicht Initialisiert haben.

Aber es funktioniert.

Jetzt habe ich mal das bei mir im Projekt eingebaut und bekomme dann die Fehlermeldung, das ScrollView initialisiert werden muss.

Gut das Habe ich dann so gemacht:
B4X:
Sub Activity_Create(FirstTime As Boolean)
Canvas1.Initialize(Activity)
ScrollView1.Initialize(500dip)

allerdings bekomme ich dann eine andere Fehlermeldung die wie folgt ausschaut:
B4X:
chat_addrow (java line: 319)


java.lang.NullPointerException


   at anywheresoftware.b4a.objects.ViewWrapper.getWidth(ViewWrapper.java:121)
   at yamu.app.chat._addrow(chat.java:319)
   at yamu.app.chat._activity_create(chat.java:273)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
   at yamu.app.chat.afterFirstLayout(chat.java:89)
   at yamu.app.chat.access$100(chat.java:16)
   at yamu.app.chat$WaitForLayout.run(chat.java:74)
   at android.os.Handler.handleCallback(Handler.java:615)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:213)
   at android.app.ActivityThread.main(ActivityThread.java:4787)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
   at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException

hast du da ne Ahnung was das sein kann?

gruß
sinan tuzcu
 

klaus

Expert
Licensed User
Longtime User
Wenn Du eine View im Designer hinzufügst darfst Du sie nicht im Code initialisieren !
Wenn Du eine View im Code hinzufügst musst Du sie im Code initialisieren !

Um den Fehler finden zu können musst Du mehr Code zeigen oder besser das Projekt als zip Datei senden.

Beste Grüsse.
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hi Klaus,

hast du ne Ahnung, wie ich sinnvoller die Daten aus dem SQLite herufen kann?

B4X:
Cursor1 = SQL1.ExecQuery("SELECT  Benutzername, Mesaj, LinkAdres, Durum, Datum FROM nur" & Cepnumarasi)
   For j = 0 To Cursor1.RowCount - 1
      Cursor1.Position = j
   

             Spalte(1) = Cursor1.GetString("Benutzername")
           Spalte(2) = Cursor1.GetString("Mesaj")
           Spalte(3) = Cursor1.GetString("LinkAdres")
         Spalte(4)= Cursor1.GetString("Durum")
           Spalte(5)= Cursor1.GetString("Datum")   
         
         If Spalte(0) = Cepnumarasi Then
            AddRow("links",Spalte(2))
         Else
            AddRow("rechts", Spalte(2))
         End If

so rufe ich die Daten auf und schreibe sie in die scrollview..
leider ist es sehr langsam. d.h. die Sprechblasen, werden Zeile für Zeile eingefügt, so das ich da mit zählen kann.

Gibt es einen Weg, wie ich das beschleunigen kann?

gruß
sinan
 

klaus

Expert
Licensed User
Longtime User
Wie viele Einträge hast Du ?
Benutzt Du auch die Werte von Spalte(1), Spalte(3), Spalte(4) und Spalte(5) ?
Wenn Nein brauchst diese nicht einlesen.
Vielleicht könnte die CustomListview Classe das Vorgehen beschleunigen.
Habe aber nie Geschwindigkeitsvergleiche gemacht.
Habe auch CustomListview noch nie gebraucht.

Beste Grüsse.
 

Sinan Tuzcu

Well-Known Member
Licensed User
Longtime User
Hi Klaus,

die Einträge sind soviel, bis der user sie löscht.

im Momnet verwende ich nur die Spalte(2) aber später werde ich auch die anderen Spalten mit einziehen.

Ist customLV schneller?
war die Arbeit mit der ScrollView umsonst :)
ist es mit der CLV das gleiche wie mit der ScrolView realisierbar?

gruß
sinan
 
Top