538 Stimmen

Wie kann ich in Android die Ränder in dp programmatisch einstellen?

Unter este , este y este Thread habe ich versucht, eine Antwort auf die Frage zu finden, wie man die Ränder einer einzelnen Ansicht einstellen kann. Ich habe mich jedoch gefragt, ob es nicht einen einfacheren Weg gibt. Ich werde erklären, warum ich diesen Ansatz lieber nicht verwenden möchte:

Ich habe eine benutzerdefinierte Schaltfläche, die Button erweitert. Wenn der Hintergrund auf etwas anderes als den Standardhintergrund gesetzt wird (entweder durch den Aufruf von setBackgroundResource(int id) o setBackgroundDrawable(Drawable d) ), möchte ich, dass die Ränder 0 sind. Wenn ich dies aufrufe:

public void setBackgroundToDefault() {
    backgroundIsDefault = true;
    super.setBackgroundResource(android.R.drawable.btn_default);
    // Set margins somehow
}

Ich möchte, dass die Ränder auf -3dp zurückgesetzt werden (ich habe bereits gelesen ici wie man von Pixeln in dp konvertiert, so dass ich, sobald ich weiß, wie man Ränder in px einstellt, die Konvertierung selbst vornehmen kann). Aber da dies in der Datei CustomButton Klasse kann das Elternteil von LinearLayout zu TableLayout variieren, und ich möchte nicht, dass er sein Elternteil erhält und die Instanz dieses Elternteils überprüft. Das wird auch ziemlich inperformant sein, denke ich.

Auch beim Aufruf (mit LayoutParams) parentLayout.addView(myCustomButton, newParams) Ich weiß nicht, ob sie dadurch an der richtigen Stelle eingefügt wird (ich habe es noch nicht ausprobiert), z. B. an der mittleren Taste einer Fünferreihe.

Frage: Gibt es eine einfachere Möglichkeit, den Rand eines einzelnen Buttons programmatisch zu setzen? außer der Verwendung von LayoutParams?

EDIT: Ich weiß, der LayoutParams Weg, aber ich möchte eine Lösung, die vermeidet, jede unterschiedliche Container-Typ zu behandeln:

ViewGroup.LayoutParams p = this.getLayoutParams();
    if (p instanceof LinearLayout.LayoutParams) {
        LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof RelativeLayout.LayoutParams) {
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
    else if (p instanceof TableRow.LayoutParams) {
        TableRow.LayoutParams lp = (TableRow.LayoutParams)p;
        if (_default) lp.setMargins(mc.oml, mc.omt, mc.omr, mc.omb);
        else lp.setMargins(mc.ml, mc.mt, mc.mr, mc.mb);
        this.setLayoutParams(lp);
    }
}

Denn this.getLayoutParams(); gibt eine ViewGroup.LayoutParams die nicht über die Attribute topMargin , bottomMargin , leftMargin , rightMargin . Die mc-Instanz, die Sie sehen, ist nur eine MarginContainer die versetzte (-3dp) Ränder und (oml, omr, omt, omb) sowie die ursprünglichen Ränder (ml, mr, mt, mb) enthält.

27voto

Fangming Punkte 22809

Hier ist die umfassende Antwort mit den jüngsten Aktualisierungen:

Schritt 1, zur Aktualisierung der Marge

Der Grundgedanke besteht darin, die Marge herauszuholen und sie dann zu aktualisieren. Die Aktualisierung erfolgt automatisch, und Sie müssen sie nicht zurücksetzen. Um die Layout-Parameter zu erhalten, rufen Sie einfach diese Methode auf:

LayoutParams layoutParams = (LayoutParams) yourView.findViewById(R.id.THE_ID).getLayoutParams();

Le LayoutParams ergibt sich aus dem Layout Ihrer Ansicht. Wenn die Ansicht aus einem linearen Layout stammt, müssen Sie Folgendes importieren LinearLayout.LayoutParams . Wenn Sie relatives Layout verwenden, importieren Sie LinearLayout.LayoutParams , usw.

Wenn Sie nun den Rand mit Layout_marginLeft , Right usw., müssen Sie die Marge auf diese Weise aktualisieren

layoutParams.setMargins(left, top, right, bottom);

Wenn Sie den Spielraum mit der neuen layout_marginStart müssen Sie die Marge auf diese Weise aktualisieren

layoutParams.setMarginStart(start);
layoutParams.setMarginEnd(end);

Schritt 2: Aktualisierung der Marge in dp

Alle beiden oben genannten Arten der Aktualisierung des Randes werden in Pixeln aktualisiert. Sie müssen eine Übersetzung von dp in Pixel vornehmen.

float dpRatio = context.getResources().getDisplayMetrics().density;
int pixelForDp = (int)dpValue * dpRatio;

Geben Sie nun den berechneten Wert in die oben genannten Funktionen zur Aktualisierung des Spielraums ein, und Sie sollten fertig sein

16voto

Morozov Punkte 3987

In Kotlin wird es so aussehen:

val layoutParams = (yourView?.layoutParams as? MarginLayoutParams)
layoutParams?.setMargins(40, 40, 40, 40)
yourView?.layoutParams = layoutParams

10voto

Ian Wong Punkte 1557

Layout_margin ist eine Einschränkung, die eine untergeordnete Ansicht an ihre übergeordnete Ansicht weitergibt. Es ist jedoch die Aufgabe des Elternteils zu entscheiden, ob er einen Rand zulassen will oder nicht. Durch die Einstellung Android:layout_margin="10dp" bittet das Child die übergeordnete View-Gruppe um die Zuweisung von Platz, der 10dp größer als seine tatsächliche Größe. (padding="10dp" bedeutet andererseits, dass die untergeordnete Ansicht ihren eigenen Inhalt erstellt. 10dp kleiner .)

Folglich, nicht alle ViewGroups beachten den Rand . Das berüchtigtste Beispiel ist die Listenansicht, bei der die Ränder der Elemente ignoriert werden. Bevor Sie setMargin() zu einem LayoutParam, sollten Sie immer sicherstellen, dass sich die aktuelle Ansicht in einer ViewGroup befindet, die Margin unterstützt (z. B. LinearLayouot oder RelativeLayout), und das Ergebnis von getLayoutParams() zu den gewünschten LayoutParametern. ( ViewGroup.LayoutParams hat nicht einmal setMargins() Methode!)

Die nachstehende Funktion sollte das Problem lösen. Stellen Sie jedoch sicher, dass Sie RelativeLayout durch den Typ der übergeordneten Ansicht ersetzen.

private void setMargin(int marginInPx) {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) getLayoutParams();
    lp.setMargins(marginInPx,marginInPx, marginInPx, marginInPx);
    setLayoutParams(lp);
}

10voto

neferpitou Punkte 1542

Mit dieser Methode können Sie die Marge en DP

public void setMargin(Context con,ViewGroup.LayoutParams params,int dp) {

        final float scale = con.getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int pixel =  (int)(dp * scale + 0.5f); 

        ViewGroup.MarginLayoutParams s =(ViewGroup.MarginLayoutParams)params;
        s.setMargins(pixel,pixel,pixel,pixel);

        yourView.setLayoutParams(params);
}

UPDATE

Sie können die Parameter entsprechend Ihren Anforderungen ändern.

9voto

Shaon Punkte 2020

Kotlin verwenden,

        yourLayoutId.updateLayoutParams<ViewGroup.MarginLayoutParams> {
            setMargins(15,15,15,15)
        }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X