Legen Sie die Ränder in einem LinearLayout programmgesteuert fest


266

Ich versuche, Java ( nicht XML ) zu verwenden, um ein LinearLayout mit Schaltflächen zu erstellen, die den Bildschirm ausfüllen und Ränder haben. Hier ist Code, der ohne Ränder funktioniert:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Das funktioniert also gut, aber wie um alles in der Welt geben Sie den Schaltflächen Ränder, damit zwischen ihnen Platz ist? Ich habe es versucht LinearLayout.MarginLayoutParams, aber das hat kein weightMitglied, also ist es nicht gut. Und es funktioniert auch nicht, wenn Sie es lpin seinem Konstruktor übergeben.

Ist das unmöglich Weil es sicher so aussieht und es nicht die erste Android-Layoutaufgabe wäre, die Sie nur in XML ausführen können.


1
developer.android.com/reference/android/view/… , int, int, int) Anstelle von layoutParams.setMargins (30, 20, 30, 0); Sie setzen layoutParams.setMargins (30dp, 20dp, 30dp, 0dp);
DarthestVader

3
setMargins nimmt int als Argumente. Sie können "dp" nur mit XML-Attributen
bereitstellen

Antworten:


496

Hier ist ein kleiner Code, um dies zu erreichen:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(30, 20, 30, 0);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);


25
Es sieht so aus, als ob die Randparameter in Pixel eingestellt sind. Wie kann man sie in dps setzen?
Artem Russakovskii

30
@ArtemRussakovskii Wie die meisten Funktionen in Android nehmen sie Pixel auf. Ich schlage eine globale Utility-Funktion vor, die Dips in px konvertiert. Das habe ich in all meinen Apps getan. Android API ist scheiße.
mxcl

7
@ MaxHowell Das habe ich letztendlich getan. Es ist unglaublich, dass solche grundlegenden Dinge manchmal fehlen.
Artem Russakovskii

5
@ArtemRussakovskii - Verwenden Sie TypedValue.applyDimension (...), um DIP in PX zu konvertieren. Siehe stackoverflow.com/questions/2238883/…
Gautam

64

Das funktioniert also gut, aber wie um alles in der Welt geben Sie den Schaltflächen Ränder, damit zwischen ihnen Platz ist?

Sie rufen setMargins()das LinearLayout.LayoutParamsObjekt an.

Ich habe versucht, LinearLayout.MarginLayoutParams zu verwenden, aber das hat kein Gewichtselement, also ist es nicht gut.

LinearLayout.LayoutParamsist eine Unterklasse von LinearLayout.MarginLayoutParams, wie in der Dokumentation angegeben .

Ist das unmöglich

Nein.

Es wäre nicht die erste Android-Layout-Aufgabe, die Sie nur in XML ausführen können

Gerne können Sie diesen Anspruch nachweisen.

Persönlich ist mir nichts bekannt, was nur über XML und nicht über Java-Methoden im SDK erreicht werden kann. Tatsächlich muss per Definition alles über Java möglich sein (allerdings nicht unbedingt über SDK-erreichbare Methoden), da XML kein ausführbarer Code ist. Aber wenn Sie etwas wissen, weisen Sie darauf hin, denn das ist ein Fehler im SDK, der eines Tages behoben werden sollte.


2
Ha, ok ich verstehe jetzt. War ein bisschen verloren im Layout-System, was ziemlich kompliziert ist. Ich glaube nicht, dass es sowieso möglich ist, layout_widgth / height zur Laufzeit festzulegen.
Timmmm

2
Und es gibt keine Möglichkeit, den Stil festzulegen
Timmmm

1
Ich hatte kein Problem mit der Einstellung von Breite und Höhe zur Laufzeit über LayoutPararms. Ich Begriffe von Stilen ... ja, es gibt einen Grund, warum ich sie nicht benutze. :-)
CommonsWare

6
Ich möchte wissen, warum es so eine PITA ist, programmgesteuert eine Benutzeroberfläche zu generieren
Jemand irgendwo

3
Es hat ewig gedauert, bis mir klar wurde, dass ich vor ein paar Tagen die falschen LayoutParams importiert habe, die Margins nicht unterstützen ... Als ich diese Antworten las, beschloss ich, meinen Import zu entfernen. Es gibt über 10 Optionen D: Ich habe mich für linearLayout.LayoutParams entschieden. Funktioniert.
Doomsknight

31

Um Elemente direkt zu Elementen hinzuzufügen (einige Elemente ermöglichen die direkte Bearbeitung von Rändern), haben Sie folgende Möglichkeiten:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

... dies funktioniert, ohne dass Sie das umgebende Layout kennen / bearbeiten müssen. Beachten Sie die Prüfung "instanceof", falls Sie versuchen, dies für etwas auszuführen, das keine Ränder unterstützt.


2
Es ist genau das, wonach ich suche.
DJDance

21

Aufgrund der unterschiedlichen Pixeldichten des Gerätebildschirms ist es gut, immer die DIPEinheit zu verwenden, um den Rand programmgesteuert einzustellen. Wie unten_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 

Hoffe das wird helfen.


10

Ich habe Ränder direkt mit dem folgenden Code eingerichtet

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Hier ist nur zu beachten, dass LayoutParamsfür das folgende Paket importiert werden sollte android.widget.RelativeLayout.LayoutParams, da sonst ein Fehler auftritt.


7

Versuche dies

 LayoutParams params = new LayoutParams(
            LayoutParams.WRAP_CONTENT,      
            LayoutParams.WRAP_CONTENT
    );
    params.setMargins(left, top, right, bottom);
    yourbutton.setLayoutParams(params);

7
 MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
 layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);

2
„Obwohl dieser Code die Frage beantworten kann, ist es besser, die Erklärung des Codes hier aufzunehmen.
Xenteros

4

Versuche dies:

MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;

3
/*
 * invalid margin
 */
private void invalidMarginBottom() {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) frameLayoutContent.getLayoutParams();
    lp.setMargins(0, 0, 0, 0);
    frameLayoutContent.setLayoutParams(lp);
}

Sie sollten den Typ der Ansichtsgruppe der Ansicht kennen. Im obigen Code möchte ich beispielsweise den Rand des FrameLayout ändern, und die Ansichtsgruppe des FrameLayout ist ein RelativeLayout . Sie müssen also zu (RelativeLayout.LayoutParams) wechseln


0

Hier eine einzeilige Lösung:

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.