German Scalierung von Buttons usw.

Heinz

Active Member
Licensed User
Longtime User
Hallo,
Da ich nur ein paar Controls habe und mit dem Designer noch
nicht so fit bin, möchte ich, daß das Aussehen bei den gängigen
Smartphones mit versch. Bildschirmgrößen in etwa gleich ist.

Hab jetzt die Erfahrung gemacht, daß mein bisheriges Positionieren
bei Kollegen mit Smartphones mit größeren Bildschirmen die
Buttons durcheinander bringt :

Listview1.AddToActivity(Activity, 0, 180, 100%x, 80%y)
Activity.AddView(Button3, 300, 110, 40%x, 10%y)
Activity.AddView(Button2, 0,110, 20%x, 10%y)
Activity.AddView(Edit1, 160,10, 60%x, 10%y)
Activity.AddView(Button1, 0, 10, 20%x, 10%y)

Da müßte es doch möglich sein, daß man immer das gleiche Layout
darstellen könnte :
Button1 Edit1
Button2 Button3
Listview (ganze Breite + restliche Höhe)

Das ganze sollte bei Portait und Landscape möglichst gleich aussehen.

Nimmt man da besser %X und %y oder dip ?
Oder sollte ich da besser mit Activity.Left, Activity.Width und Activity.Height
arbeiten ?

Das Listview muß ich ja sowieso mit Code erstellen (CodeModule Table).

Hat da jemand ein Tipp für mich ?
 

klaus

Expert
Licensed User
Longtime User
Erster Punkt:
Nie mit Pixeln arbeiten, denn je nach Pixelgrösse gibt es grosse Unterschiede.
dip Werte oder %x / %y Werte verwenden.
Zum Beispiel, in dieser Zeile ist Left mit 300 Pixeln angegeben, aber Width mit 40%x !?
Activity.AddView(Button3, 300, 110, 40%x, 10%y)
Was ist die Bildschirmauflösung die deinem Layout zu Grund liegt ?

In deinem Fall würde Ich folgendes vorschlagen:
Benutze dip Werte für die Top und Height Werte der Buttons und Edit1.
Benutze %x Werte für die Left und Width Werte der Buttons und Edit1.
Fülle den Rest der Bildschirmhöhe mit der Table Class.
 

Heinz

Active Member
Licensed User
Longtime User
Werde ich mal versuchen.
Mein Smartphone hat z.B. 4 Inch, die der
Kollegen sind aber unterschiedlich groß.

Da kommt es wahrscheinlich nur auf die Höhe
der Buttons und dem Editfeld an. Horizontal
reicht es auf alle Fälle. Da könnten feste Werte
verwandt werden.
Also wie du schon sagtest : Aufpassen wegen der
Unterschiede in der Pixelgröße. Ich dachte, dip-Werte
beziehen sich auf Pixel.
 

klaus

Expert
Licensed User
Longtime User
Geräte mit 4'' Bildschirm können verschiedene Auflösung haben.
Zum Beispiel.
320 / 480 / 160
480 / 800 / 240
In diesen Beispielen ist die Grösse der Pixel verschieden und auch das Breite / Höhe Verhältniss.
320 / 480 / 160 heisst: 320 Pixel in der Breite, 480 Pixel in der Höhe und 160 Pixel pro Inch.
480 / 800 / 240 heisst: 480 Pixel in der Breite, 800 Pixel in der Höhe und 240 Pixel pro Inch. Hier sind die Pixelhöhe und PixelBreite 1.5 mal kleiner als im ersten Beispiel.
dip Werte heisst density independant pixel (Dichte unabhängige Pixel).
In dieser Zeile Activity.AddView(Button3, 300, 110, 40%x, 10%y) sind 300 und 110 absolute Werte keine dip Werte.
Das heisst dass 300 im ersten Beispiel ungefähr einer Breite von 0.94 Inch entspricht und im zweiten Beispiel 0.63 Inch. Visuel also kleiner.
Wenn Du die Zeile so änderst Activity.AddView(Button3, 300dip, 110dip, 40%x, 10%y) sind die Breiten in beiten Beispielen gleich (0.94 Inch).

Mit meinem Vorschlag füllen die Buttons und Edit1 die volle Breite des Bilschirms.
Mit festen Werten kannst Du rechts, je nach den Bildschirmen, lehren Platz bekommen.
Die Höhen sind aber feste Werte, es gibt keinen Grund diese an die Höhe des Bildschirmes anzupassen.
Wenn das Breite / Höhe Verhältniss kleiner ist, ist es besser den grösseren Platz im unteren Teil des Bildschirms fur die ListView zu verwenden.
 

Heinz

Active Member
Licensed User
Longtime User
Werde ich dann auch mal probieren.
Ist halt als Windowsprogger etwas schwierig.
Bei Windows ist halt ein Pixel ca. 1 mm groß.
Wenn ich da mit festen Werten meine Buttons etc.
setze, sind die auch immer an der gleichen Stelle
und auch genau so groß, egal, wie groß der Bildschirm
ist. Klar ist, daß die Buttons auf einem 21 Zoll Bildschirm
optisch etwas kleiner wirken, als bei z.B. 14 Zoll.

Was mich vor 2 Stunden verwundert hat :
Ich hatte das Programm einem Gastronomen geschickt.
Dessen Smartphone ist auch größer. Bloß bei ihm werden
die Buttons so schön angezeigt, so wie bei mir. Da hätte
ich jetzt eher gedacht, daß ich wieder Button-Salat sehe.

Was ich noch fragen wollte :
Wäre es sogar nicht besser, die Werte der Activity
(Activity.Top, Activity.Left, Activity.Width und Activity.Height)
hierfür zu nutzen. Die Activity ist ja praktisch vergleichbar
mit dem Windowsfenster. Wenn das denn dip-Werte sind,
könnte man ja von diesen Koordinaten ausgehen.
 

Heinz

Active Member
Licensed User
Longtime User
So, habe jetzt alles mit dip positioniert. Auch die Größen der Buttons
und Editfeld habe ich mit dip angegeben. Scheint so, daß auch
bei Landscape (wenigstens bei mir) keine Neupositionierung bzw.
Größenänderung erforderlich ist.

Die Elemente sollen ja nur oben links beginnend angeordnet werden.
Wieviel Platz nach rechts bei Landscape frei bleibt, ist für mich im
Moment bedeutungslos, da es ja nur wenige Elemente sind.
Außerdem fängt man ja immer links an, ob beim Schreiben im
Texteditor, Blatt Papier, Malen oder sonstiges. Insofern kann ich
die tatsächliche Breite des Bildschirm außen vor lassen.

Mal gespannt, was die Kollegen sagen, bzw. ob es auch dort vernünftig
angezeigt wird.

Und Danke für deine Erläuterungen.
 

klaus

Expert
Licensed User
Longtime User
Wäre es sogar nicht besser, die Werte der Activity
(Activity.Top, Activity.Left, Activity.Width und Activity.Height)
hierfür zu nutzen.
Nein.
Activity.Left = 0
Activity.Top = 0
Activity.Width = 100%x
Activity.Height = 100%y

Du solltest aber die ListView an die Bildschirmhöhe anpassen.
Beispiel:
B4X:
Dim Top as Int
Top = Button2.Top + Button2.Height + 10dip
Listview1.AddToActivity(Activity, 0, Top, 100%x, 100%y - Top)
 

Heinz

Active Member
Licensed User
Longtime User
Top = Button2.Top + Button2.Height + 10dip
Listview1.AddToActivity(Activity, 0, Top, 100%x, 100%y - Top)

Da fehlt mir aber unten ca. 1 cm.
Mach ich halt nur 100%y.

Da ich nun weitermachen will, noch eine Frage :
Wenn ich nun auf eine Zelle lang klicke (Cell_LongClick)
hätte ich gerne eine Maske mit Feldern zum Editieren und
zurückspeichern der Row. Mit einem Button 'fertig' kehrt dann
nach dem Update der Row bzw. Speichern der .csv zum
Hauptschirm zurück.

Selbstdefinierte Dialoge wäre das Stichwort.
Kann man da auch selbst definierte Layouts via Designer
verwenden bzw. einfach drüber klatschen und bei Rückkehr
zum Hauptbildschirm einfach wieder entfernen ?

Oder muß das unbedingt mit einem TabControl (Panel)
gemacht werden ?
 
Last edited:

Heinz

Active Member
Licensed User
Longtime User
Ist kein Problem, nur eine Frage.
Ich glaube, ich habe was im Forum von Erel gefunden.
Das ist der Code bisher :


Die Buttons, Edits und Labels sind oben definiert.
Die muß ich natürlich im Designer genauso benennen
und im Hauptprogramm noch abfragen.
Das Layout mache ich mir noch.

B4X:
#Region Module Attributes
    #FullScreen: False
    #IncludeTitle: True
    #ApplicationLabel: Preise
    #VersionCode: 1
    #VersionName:
    #SupportedOrientations: unspecified
    #CanInstallToExternalStorage: False
#End Region

'Activity module
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim phone1 As Phone
End Sub

Sub Globals
    'These global variables will be redeclared each time the activity is created.
    'These variables can only be accessed from this module.
    Dim z As String
    Dim Top As Int
    Dim List1 As List
    Dim Listview1 As Table
    Dim Edit1 As EditText
    Dim Button1, Button2, Button3 As Button
    ' Definitionen für das Layout
    Dim LButton1, Fertig As Button
    Dim Label1, Label2, Label3, Label4, Label5 As Label
    Dim LEdit1, LEdit2, LEdit3, LEdit4, LEdit5 As EditText

End Sub

Sub Activity_Create(FirstTime As Boolean)
    ReadList
    Button1.Initialize("Button1")
    Button2.Initialize("Button2")
    Button3.Initialize("Button3")
    Button1.Text = "Suche"
    Button2.Text = "Ende"
    Button3.Text = "Liste laden"
    Edit1.Initialize("Edit1")
    Activity.AddView(Button1, 10dip, 10dip, 60dip, 40dip)
    Activity.AddView(Edit1,   80dip,10dip, 180dip, 40dip)
    Activity.AddView(Button2, 10dip,60dip, 60dip, 40dip)
    Activity.AddView(Button3, 80dip, 60dip, 60dip, 40dip)
    Listview1.Initialize(Me, "Listview1", 5,Gravity.LEFT, True)
    Top = Button2.Top + Button2.Height + 10dip
    Listview1.AddToActivity(Activity, 0, Top, 100%x, 100%y) ' Listview unter letzten Button
    Listview1.SetHeader(Array As String("WG", "ARTNR", "NAME", "EINH", "PREIS"))
    If Activity.width > Activity.height Then
    'landscape
    Listview1.ClearAll
    Listview1.LoadTableFromCSV2(File.DirAssets, "Preise.csv", True, ",", True)
    Else 
    'portrait
    Listview1.ClearAll
    Listview1.LoadTableFromCSV2(File.DirAssets, "Preise.csv", True, ",", True)
    End If
End Sub

Sub Activity_Resume
 
End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub ReadList
    If File.Exists(File.DirAssets, "Preise.csv") Then
       List1 = File.ReadList(File.DirAssets, "Preise.csv")
    Else
       Msgbox("Kann Datei nicht laden !", "Fehler !")
    End If
End Sub

Sub Button1_Click
   Dim Liste As List 
   Dim such As String
   Dim zeile As String
   Dim str1() As String
   Dim gefunden As Int
   Liste.Initialize
   gefunden = 0
   such = Edit1.Text
   such = such.ToUpperCase
   Liste.Add("WG,ARTNR,NAME,EINH,PREIS")
   For i = 1 To List1.Size - 1
       zeile = List1.Get(i)
       If zeile.IndexOf(such) <> -1 Then
             gefunden = gefunden + 1
          Liste.Add(zeile)
       End If  
   Next
   If gefunden > 0 Then
         File.WriteList(File.DirInternalCache, "such.csv", Liste)
      Listview1.ClearAll
      Listview1.SetHeader(Array As String("WG", "ARTNR", "NAME", "EINH", "PREIS"))
      Listview1.LoadTableFromCSV2(File.DirInternalCache, "such.csv", True, ",", True)
    Else
      Msgbox("Keine Einträge gefunden !", "Info")   
    End If
    phone1.HideKeyboard(Activity)
End Sub

Sub Button3_Click
    Listview1.ClearAll
    Listview1.LoadTableFromCSV2(File.DirAssets, "Preise.csv", True, ",", True)
End Sub

Sub Fertig_Click
    ' Daten übernehmen und Layout entfernen
End Sub

Sub Listview1_CellClick(Col As Int, Row As Int)
    Msgbox(Listview1.GetValue(1, Row) & "," & Listview1.GetValue(2, Row) &"," & Listview1.GetValue(4, Row), "Gewählt :")
End Sub

Sub Listview1_Cell_LongClick
    ' Hier das Layout laden 
    'Activity.LoadLayout("Fenster2")
End Sub

Sub Button2_Click
    phone1.SetScreenOrientation(1)
    Activity.Finish
 
End Sub

Wäre das die richtige Vorgehensweise ?
Wird das Layout mit RemoveView() entfernt ?
 

klaus

Expert
Licensed User
Longtime User
Das ist der Code bisher :
Wo ist der Code.

Du hast zwei Möglichkeiten:
Ein neue Activity definieren oder das Layout in einem Panel definieren.
Eine neue Activity ist eigentlich Standard in Android.
Man kann aber auch ein Panel verwenden das den ganzen Bildschirm füllt.
Das Panel kann man mit der Visible Eigenschaft anzeigen oder verstecken.
Man muss eine leere Panel1_Click Routine einfügen um die Events der darunter liegenden Views abzufangen, oder die anderen Layouts auch auf Panesl definieren und nur ein Panel zur gleichen Zeit anzeigen.
Du solltest dir mal diesen Thread anschauen: Different examples with 2 layouts
Du kannst die auch die SQLiteLight Beispiele in meiner Unterschrift anschauen.
 

Heinz

Active Member
Licensed User
Longtime User
Ich denke mal, daß ich da mit Panels arbeiten werde.
Mit Panel.AddView() kann ich dann codemäßig meine
Buttons, Editfelder usw. hinzufügen. Da kann ich auch
bequem mein Table-View (Codemodule von Erel) nach
Bedarf hinzufügen, was ja beim Designer nicht klappt.

Mit dem Designer und den Layouts bin ich noch nicht
ganz klar, besonders was das Tableview betrifft.
Wenn ich nun unter die Buttons im ersten Layout
das Tableview per Code dranhänge, wird das Grid
beim erneuten Laden eines Layouts gelöscht ? Das
Grid möchte ich ja nicht überall (in jedem Layout)
haben.

Ich glaube, daß es erstmal mit einem Panel
einfacher geht.
 

klaus

Expert
Licensed User
Longtime User
Da kann ich auch
bequem mein Table-View (Codemodule von Erel) nach
Bedarf hinzufügen, was ja beim Designer nicht klappt.
Table ist ein Class Modul.
Die letzte Version der Table Class ist [Class] Flexible Table.
In der nächsten Version von B4A kann man CustomViews auch im Designer hizufügen.
 

Joe73

Active Member
Licensed User

Hallo Klaus,
ich bin auch gerade dabei mich mit der Auflösung des Displays zu beschäftigen um eine bestimmte Anzahl von
Werten auf der Abzisse im richtigen Maßstab anzugeben bzw. zu zeichnen.
Nun bin ich auf Deinen Beitrag hier gestoßen und habe dazu eine Frage:
Ist Dir da vielleicht ein Fehler unterlaufen?
Das Display im ersten Beispiel hat die Auflösung von 320 x 480 Pixel und 160 Pixel je Zoll.
d.h. dann also 2 x 160 Pixel(je Zoll) = 320 - also 2 Zoll Breite... ( 320/160 = 2)
300 Pixel sind doch dann nicht 0,94 Zoll sondern 300pixel/160pixel = 1,875 Zoll
Oder sehe(rechne) ich hier etwas falsch?
Ich bin am überlegen ob ich bei der Darstellung des Charts nicht doch mit Pixeln arbeiten soll?
Mit GetDeviceLayoutValues kann ich mir doch die Auflösung angeben lassen und somit die Umrechnungswerte ermitteln.
Wenn ich z.B. eine Auflösung von 1080pixel habe in der Breite dann könnte ich je Tag 2 Pixel nehmen und den Rest als Rand.
also 1080 - 2 x 365 = 350, d.h. rechts und links je 125pixel Rand.
Kann man das so machen oder doch lieber in dip umwandeln?
Über die Vorgehensweise bei der Nutzung von Dip Werten bin ich mir noch nicht ganz im klaren.
Das Beispiel mit der Darstellung einer Sinuskurve in dem Programm Charts habe ich mir bereits
angesehen und etwas damit "gespielt"

Möchte hier auch gleich die Gelegenheit nutzen und allen ein gesundes Neues Jahr zu wünschen und
mich für die umfangreichen und fundierten Hilfen in diesem Forum zu bedanken...

Gruß Jürgen
 

klaus

Expert
Licensed User
Longtime User
300 Pixel sind doch dann nicht 0,94 Zoll sondern 300pixel/160pixel = 1,875 Zoll
Da hast Du natürlich Recht!
Vom Prinzip her würde Ich es, in diesem Fall, auch so machen.
Denn dann hast Du eine ganze Zahl von Pixeln pro Tag.
Aber bei mir wären es dann 175 Pixel pro Rand.

Was sind dip (density indepemdent pixels) Werte.
Diese Werte sind Dichte unabhängig, das heisst dass eine Breite von 160dip ungefähr 1 Zoll breit ist, unabhängig von der Pixel Dichte.

Du hättest dann noch die Möglichkeit mit HorizontalScrollView oder ScrollView2D zu arbeiten wo die Grösse des Charts breiter und im zweiten Fall auch höher als der Bildschirm sein könnte.

Aber das ist dann Alles abhängig von den verschiedenen Bildschirmgrössen und ist auch 'Geschmacksache'.
 

Joe73

Active Member
Licensed User
Hallo,

Danke für Deine Ausführungen.
Da ist es mir also auch passiert, etwas verrechnet...
Gruß Jürgen
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…