German Werte im Designer auslesen

pucki

Active Member
Licensed User
Gibt es eine Möglichkeit die Werte auszulesen die im Designer stehen ??

Ok die Frage muss ich erklären ;)

Ich habe im Designer ein Layout gemacht (Breite = 350 // Höhe = 640)
Auf dem Layout befindet sich ein LABEL_1. Wenn ich das anklicke, steht bei TOP 600 als Wert.

Kann ich diesen Wert irgendwie in den Code übernehmen.

Bevor sich einer Fragt wieso. Wenn ich diesen Wert übernehme dann kann ich mir (laut ersten Tests) das ganze Anpassen mit 2 Layouts u.s.w. sparen.

Ich habe es auf 3 Geräte getestet (alles Samsungs) und mein Code passte das Design jedes mal perfekt an, wenn ich in der Activity_Create folgenden Befehl eingeben habe :

LABEL_1.TOP = 600

Dann die Position danach neu berechnen mit den Code :
faktor_y = Activity.Height / 640
LABEL_1.TOP = LABEL_1.TOP * faktor_y

Sitzt perfekt auf 2 x Handy + 1 Tablett mit alle unterschiedliche Größen.


Muss ich also die Werte von Hand übertragen.


Ps: Die selbe Technik benutzt ich bei Visual-Basic seit Jahren was dazu führt, das mein Prg.-Fenster unbegrenzt in beide Richtungen skaliert werden kann.

Gruß

Pucki
 

MarkusR

Well-Known Member
Licensed User
Also das Problem scheint zu sein das die Positions Werte nach dem Laden des Layouts bereits scaliert sind bzw. nicht wie im Designer ursprünglich.
 

klaus

Expert
Licensed User
Wie Markus schon angedeutet hat, musst Du AutoScale im Designer wegnehmen.
Diese Formel funktioniert nur wenn die Bildschirmskala des Gerätes 1 ist, was in modernen Geräten .
faktor_y = Activity.Height / 640
Geänderte Formel:
faktor_y = Activity.Height / 640 / GetDeviceLayoutValues.Scale
Dann noch folgende Frage.
Ist 640 die ganze Höhe des Bildschirms mit den beiden oberen Zeilen?
Wenn ja, musst Du die Höhe dieser beiden Zeilen abziehen.
Bei manchen Geräten gibt es auch noch unten eine Zeile, mit dem Home und Back Button.
Diese Höhe musst Du auch noch abziehen.
Auf meinem Samsung Galaxy S8 sind das 128dip.
Die Bildschirmhöhe ist 2220 Pixel une 100%y ergeben 1836.
(2220 - 1836) / 3 = 128
3 ist die Bildschirmskala.
In früheren Android Versionen waren es 50dip.
Aber leider je nach Android Version ändert sich das.
 
Last edited:

pucki

Active Member
Licensed User
Wie Markus schon angedeutet hat, musst Du AutoScale im Designer wegnehmen.
Geänderte Formel:
faktor_y = Activity.Height / 640 / GetDeviceLayoutValues.Scale
DAS ist die Lösung. Den Befehl kannte ich noch nicht. Ich stelle einfach das Layout auf Vollbildschirm aktuell.

Wie Markus schon angedeutet hat, musst Du AutoScale im Designer wegnehmen.
Falls du das "AutoScale " im Script des Designer meinst, das hat keine Auswirkung auf den Code.

Wenn ja, musst Du die Höhe dieser beiden Zeilen abziehen.
Bei manchen Geräten gibt es auch noch unten eine Zeile, mit dem Home und Back Button.
Gibt es ein Befehl das festzustellen ob die Aktiv sind (visible ) oder nicht. ?? Das Handy meiner Schwester ist nämlich ein A7 mit Android 9. Da hab ich das elend erst gemerkt.

Gruß

Pucki
 

klaus

Expert
Licensed User
Gibt es ein Befehl das festzustellen ob die Aktiv sind (visible ) oder nicht.
Ja.
Mit GetDeviceLayoutValues.Height bekommst Du die Höhe des Bildschirms.
Mit 100%y bekommst Du die für dein Programm verfügbare Bildschirmhöhe.
Auf meinem Samsung Galaxy S8 bekomme ich folgendes:
Mit den beiden oberen Zeilen.
Wenn die untere Navigation Bar aktiv ist:
GetDeviceLayoutValues.Height = 2076
100%y = 1836
Ohne der Navigation Bar:
GetDeviceLayoutValues.Height = 2220
100%y =1980
Die Differenz der beiden Werte entspricht der Höhe der beiden oberen Zeilen.
Also (2220 - 1980) / 3 = 80dip
Ob diese Zeilen aktiv sind oder nicht weisst Du ja ais Programmierer, denn Du definierst ja ob Du die anzeigen willst oder nicht.
 

pucki

Active Member
Licensed User
Ja.
Ob diese Zeilen aktiv sind oder nicht weisst Du ja ais Programmierer, denn Du definierst ja ob Du die anzeigen willst oder nicht.
Na das löst doch alle Probleme. ;) Ich brauche Platz am Bildschirm ;) ergo Abschalten was Platz braucht.

Und das Problem mit den Tablett oder Handy u.s.w. ist damit auch gelöst. Und ich brauche nur noch EIN Design. *Freuwiedoll*

Das ist in meinen Augen die perfekte Lösung. Weil man 2 !!! Skalierfaktoren braucht. X + Y. Ich bin wegen meiner Erfahrung der Meinung das b4X nur 1 Skalierfaktor benutzt. Das führt bei meinen Apps dazu das sie in der Breite perfekt sind, aber NICHT in der Höhe.

Vielleicht mache ich auch was falsch. Aber es ist halt der Effekt den ich dauernd habe. Und da ich bisher keine Apps (sind eh nur private und werden NIE im Google-Store landen) entwickele habe ich bisher noch nie eine App gemacht die für Handy + Tablett funktionierte. Das Problem trat erst auf als meine Schwester mein Einkaufslisten-Prg. haben wollte, und Sie ein A7 kaufte. Ich habe ein A5 . Das A7 ist größer als meins.

Ich möchte aber das sie proportional gleich sind und den Bildschirm ausfüllen. Klar wirken die dann bei großen Bildschirmen etwas wuchtig. Aber das finde ich besser als wenn sie mickrig klein in einer Ecke hocken. Wie schon gesagt, meine VB-Prg. werden durch das Resize-Ereignis neu skaliert. (wobei ich aus Technischen Gründen ein Minimum von 640 x 480 habe)

Hier wird das selbe "Ereignis" halt bei Starten der App ausgelöst. Mit genau der selben Technik ;)

Wie gesagt ich bin glücklich und danke dir lieber Klaus sehr herzlich.

Gruß

Pucki
 

klaus

Expert
Licensed User
Ich hatte vor ein Paar Jahren ein Scale Modul geschrieben welches ganau das macht.
Das Problem mit dem einzigen Skalierungsfaktor gefiehl mir damals auch nicht.
Ich mache es jetzt meitens anders.
Mit AutoScale und Anchors und DesignerScript.
Je nach dem was ich anzeigen will, gebe ich die verschiedenen Views auf ein Panel, vergrössere es mit AutoScale (AutoScaleate(0.5) und zentriere das Panel in die Mitte des Bildschirms.
 

pucki

Active Member
Licensed User
Ich hätte noch eine selten blöde Frage.
Die Werte im Designer sind doch in DIP angegeben oder. ? Und Activity.Width liefert doch auch DIP oder. ?

Wobei es mir eigentlich egal ist, solange es immer das gleiche ist ;)

Ich glaube ja, aber ich liebe nun mal keine Überraschungen die ich erst später merke. Das ist mir mal bei TWIPS passiert. (VB-Drucker-Positionierung)


Gruß

Pucki
 

klaus

Expert
Licensed User
Die Werte im Designer sind doch in DIP angegeben oder. ?
Die Werte im Designer sind DIP Werte.
Und Activity.Width liefert doch auch DIP oder.
Nein, Activity.Width oder 100%x sind Pixelwerte!
 

pucki

Active Member
Licensed User
dann kommt gleich die nächste dumme Frage.

Wie bekomme ich die synchronisiert. Also entweder dip in %x oder umgekehrt umgerechnet.

Gruß

Pucki
 

pucki

Active Member
Licensed User
Alles funktioniert in der Theorie *hoil*

Im Log weißt das System den perfekten Wert (1200) zu . Nur auf den Bildschirm stimmt der nicht.
Log("oben-w : "&hp_a_oben.Width) ergibt 1200 = perfekt. Auf den Bildschirm ist das Teil viel breiter.

Ich würde fast wetten das da irgend wo im Compiler mir noch was dazwischenfunkt und eine Nachskalierung durchführt.

Wie kann ich ALLE Skalierungen abschalten. ?

Gruß

Pucki
 

pucki

Active Member
Licensed User
Hier ein Testprojekt. Mit vielen Log's zur erklärung des Problems.

Einfach Lösung (die ich aber nicht kenne). B4A darf NICHT selbstständig skalieren. !!

Einfach gesagt. Wenn ich ein Objekt an eine Stelle im Code bzw. im Designer setze, soll es da stehen bleiben und sich nicht verändern. EGAL wie groß der Bildschirm ist. !!!!!

Sobald die CREATE- SUB aufgerufen wird, wird faktor_X + faktor_y Berechnet und dann folgende Routine aufgerufen.
B4X:
    For Each v As View In Activity.GetAllViewsRecursive
        v.Top = v.top  * faktor_y
        v.left  = v.left * faktor_x
        v.Width = v.width * faktor_x
        v.Height = v.Height * faktor_y
    Next
und das selbstverständlich auch im Panel. Wobei sich die Frage stellt ob ein Panel eine eigene 0 Stellung oben Links hat. Wird aber im Test-Code nicht berücksichtigt.

Ich denke das es eine mathematisch Lösung für das Problem gibt. Aber es sollte auch ohne gehen.

Gruß

Pucki
 

Attachments

Last edited:

pucki

Active Member
Licensed User
So ich habe nun eine Lösung.
Ist zwar so ähnlich wie die berühmte Magische Kugel aber es funktioniert.

B4X:
#Region  Activity Attributes
   #FullScreen: false
   #IncludeTitle: false
#End Region

Sub Globals
  Private prg_status As String = "am laden"
end sub


Sub Activity_Create(FirstTime As Boolean)
        Activity.LoadLayout("des_leer")  '(Hauptbildschirm)
  
    my_panel_1.LoadLayout("des_einkauf")
    
    prg_status = "geladen"

    pos_setzen ' (berechnet die Pos und setzt alles )

end sub


Sub pos_setzen
    If prg_status = "am laden" Then
        Return
    End If

    faktor_x =   ((GetDeviceLayoutValues.Width) / GetDeviceLayoutValues.Scale  / 350 ) ' 350 = grösse des Layouts im Designer
    faktor_y = ((GetDeviceLayoutValues.Height ) / GetDeviceLayoutValues.Scale / 640) '640 = grösse des Layouts im Designer

    For Each v As View In Activity.GetAllViewsRecursive
        v.Top = v.Top * faktor_y
        v.left  = v.Left * faktor_x
        v.Width = v.Width * faktor_x
        v.Height = v.Height * faktor_y
    Next
' 
    my_panel_1.Visible = True
    For Each v As View In my_panel_1.GetAllViewsRecursive

        v.Top = v.Top * faktor_y
        v.left  = v.Left * faktor_x
        v.Width = v.Width * faktor_x
        v.Height = v.Height * faktor_y
        v.BringToFront
    Next
end sub
Kleiner Tipp am Rande. Wenn man Panels macht, dafür ein eigenens Layout machen mit der Grösse die es hinterher haben soll, im Verhältnis zum Hauptlayout.
Mein Hauptlayout (des_leer) ist 640 * 350 Skalfaktor 1 // Das Panel (des_einkauf.bal) hat das Layout 580 * 350 Skalfaktor 1.

Das ist zwar alles andere als perfekt, aber es tut seinen Zweck. Und ich armes Kerlchen habe 15 Std. gebraucht die Nuss zu knacken.

Gruß

Pucki
 

klaus

Expert
Licensed User
Beiliegend meine Version.
Habe auch etwas Zeit gebraucht weil auf meinem Smasung Galaxy S8 unten ein kleiner Rand blieb.
Habe endlich gefunden dass Ich, im Manifest Editior, android:targetSdkVersion="26"/ setzen musste und der Rand ist weg.
Jetzt funktioniert es OK auf meinem Smasung Galaxy S8 und auf meinem Samsung Tablet S2.
Ich habe das Layout geändert und die Standardgrösse genommen (320 * 480)
 

Attachments

pucki

Active Member
Licensed User
Wow besser wie meine ;) gebe ich ehrlich zu.

Und läuft sogar mit meiner alten 7.30 er Version. *freu*

Was ich nur nicht verstehe. Wieso musst du den " GetDeviceLayoutValues.Scale" faktor nicht berücksichtigen. ?

Aber zum Trost für deine Mühe. Ich halte die Routine für universal einsetzbar sonst hätte ich nicht soviel Zeit darin investiert.

Gruß

Pucki
 

klaus

Expert
Licensed User
Was ich nur nicht verstehe. Wieso musst du den " GetDeviceLayoutValues.Scale" faktor nicht berücksichtigen. ?
Weil ich dip Werte benutze:
faktor_x = Activity.Width / 320dip
Das ist das gleiche wie:
faktor_x = Activity.Width / GetDeviceLayoutValues.Scale / 320
Die anderen Unterschiede ist dass Ich die Standardbildschirmgrösse verwende.
Daher 320 anstatt 350.
Und dass ich Activity.Height verwende und nicht GetDeviceLayoutValues.Height.
 
Top