it-swarm.com.de

Wie kann ich in Android programmgesteuert Margen in dp einstellen?

In this , this und this thread habe ich versucht, eine Antwort zu finden, wie man die Ränder auf eine einzige Ansicht setzt. Ich habe mich jedoch gefragt, ob es keinen einfacheren Weg gibt. Ich erkläre, warum ich diesen Ansatz lieber nicht verwenden möchte:

Ich habe einen benutzerdefinierten Button, der den Button erweitert. Wenn der Hintergrund auf etwas anderes als den Standardhintergrund eingestellt ist (durch Aufruf von setBackgroundResource(int id) oder setBackgroundDrawable(Drawable d)), möchte ich, dass die Ränder 0 sind.

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 hier wie ich von Pixeln in dp umwandeln kann. Sobald ich also weiß, wie man Ränder in px setzt, kann ich die Konvertierung selbst durchführen). Da dies jedoch in der CustomButton-Klasse aufgerufen wird, kann das übergeordnete Element von LinearLayout bis TableLayout variieren, und ich möchte lieber nicht, dass er seinen Elternteil erhält und die Instanz dieses Elternteils überprüft. Das ist auch ziemlich unperformant, denke ich.

Wenn ich (mit LayoutParams) parentLayout.addView(myCustomButton, newParams) anrufe, weiß ich nicht, ob dies an der richtigen Position hinzugefügt wird (habe es jedoch nicht versucht), sagen Sie die mittlere Taste einer Fünferreihe.

Frage: Gibt es eine einfachere Methode, um den Rand einer einzelnen Schaltfläche programmgesteuert festzulegen außer LayoutParams?

EDIT: Ich kenne den LayoutParams-Weg, möchte aber eine Lösung, die den Umgang mit den verschiedenen Containertypen vermeidet:

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);
    }
}

Weil this.getLayoutParams(); einen ViewGroup.LayoutParams zurückgibt, der nicht die Attribute topMargin, bottomMargin, leftMargin, rightMargin..__ besitzt. Die mc-Instanz, die Sie sehen, ist nur eine MarginContainer, die Ränder (-3dp) und (oml, omr, omt, omb) und enthält die ursprünglichen Ränder (ml, mr, mt, mb).

321
stealthjong

Sie sollten LayoutParams verwenden, um Ihre Schaltflächenränder festzulegen:

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

Abhängig vom verwendeten Layout sollten Sie RelativeLayout.LayoutParams oder LinearLayout.LayoutParams verwenden.

Versuchen Sie Folgendes, um Ihr DP-Maß in Pixel zu konvertieren:

Resources r = mContext.getResources();
int px = (int) TypedValue.applyDimension(
        TypedValue.COMPLEX_UNIT_DIP,
        yourdpmeasure, 
        r.getDisplayMetrics()
);
660
throrin19

LayoutParams - funktioniert nicht! ! !

Benötigen Sie die Verwendung von: MarginLayoutParams

MarginLayoutParams params = (MarginLayoutParams) vector8.getLayoutParams();
params.width = 200; params.leftMargin = 100; params.topMargin = 200;

Codebeispiel für MarginLayoutParams:

http://www.codota.com/Android/classes/Android.view.ViewGroup.MarginLayoutParams

186
Lyusten Elder

Bester Weg überhaupt:

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();
        p.setMargins(left, top, right, bottom);
        view.requestLayout();
    }
}

So rufen Sie die Methode auf:

setMargins(mImageView, 50, 50, 50, 50);

Hoffe, das wird dir helfen.

92
Hiren Patel
int sizeInDP = 16;

int marginInDp = (int) TypedValue.applyDimension(
            TypedValue.COMPLEX_UNIT_DIP, sizeInDP, getResources()
                    .getDisplayMetrics());

Dann

layoutParams = myView.getLayoutParams()
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);

Oder

LayoutParams layoutParams = new LayoutParams...
layoutParams.setMargins(marginInDp, marginInDp, marginInDp, marginInDp);
myView.setLayoutParams(layoutParams);
25
sagits

Mit dieser Methode können Sie die Margin inDP

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 den Parameter ändern, der Ihren Bedürfnissen entspricht.

7
neferpitou

layout_margin ist eine Einschränkung, die ein View-Child seinem übergeordneten Element mitteilt. Es ist jedoch die Aufgabe des Elternteils, zu entscheiden, ob eine Marge zulässig ist oder nicht. Im Wesentlichen durch Festlegen von Android: layout_margin = "10dp" bittet das Kind die übergeordnete Ansichtsgruppe, Platz zuzuordnen, der 10dp größer ist als ihre tatsächliche Größe. (padding = "10dp" bedeutet dagegen, dass die untergeordnete Ansicht ihren eigenen Inhalt 10dp kleiner macht .)

Demzufolge respektieren nicht alle ViewGroups die Marge . Das notorischste Beispiel wäre die Listenansicht, bei der die Ränder von Elementen ignoriert werden. Bevor Sie setMargin() für ein LayoutParam aufrufen, sollten Sie immer sicherstellen, dass sich die aktuelle Ansicht in einer ViewGroup befindet, die Ränder unterstützt (z. B. LinearLayouot oder RelativeLayout), und das Ergebnis von getLayoutParams() in die gewünschten LayoutParams umwandeln. (ViewGroup.LayoutParams hat nicht einmal die setMargins()-Methode!)

Die Funktion unten sollte den Trick tun. 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);
}
7
Ian Wong

Hier ist die All-in-One-Antwort mit den neuesten Updates:

Schritt 1, um die Marge zu aktualisieren

Die Grundidee besteht darin, eine Marge herauszuholen und sie dann zu aktualisieren. Das Update wird automatisch angewendet und Sie müssen es nicht zurücksetzen. Um die Layoutparameter abzurufen, rufen Sie einfach diese Methode auf:

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

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

Wenn Sie jetzt den Rand mit Layout_marginLeft, Right usw. festlegen, müssen Sie den Rand auf diese Weise aktualisieren

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

Wenn Sie den Rand mit dem neuen layout_marginStart setzen, müssen Sie den Rand auf diese Weise aktualisieren

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

Schritt 2, um die Marge in dp zu aktualisieren

Alle zwei Möglichkeiten, die Marge zu aktualisieren, werden in Pixel aktualisiert. Sie müssen eine Übersetzung von dp in Pixel vornehmen.

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

Setzen Sie nun den berechneten Wert auf die obigen Margenaktualisierungsfunktionen und Sie sollten alle Einstellungen vornehmen

6
Fangming

Wenn Sie sich in einer benutzerdefinierten Ansicht befinden, können Sie getDimensionPixelSize(R.dimen.dimen_value) verwenden. In meinem Fall habe ich den Rand in LayoutParams hinzugefügt, der mit der Methode init erstellt wurde.

In Kotlin

init {
    LayoutInflater.from(context).inflate(R.layout.my_layout, this, true)
    layoutParams = LayoutParams(MATCH_PARENT, WRAP_CONTENT).apply {
    val margin = resources.getDimensionPixelSize(R.dimen.dimen_value)
    setMargins(0, margin, 0, margin)
}

in Java:

public class CustomView extends LinearLayout {

    //..other constructors

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        int margin = getResources().getDimensionPixelSize(R.dimen.spacing_dime);
        params.setMargins(0, margin, 0, margin);
        setLayoutParams(params);
    }
}
2
user2825576

Für ein schnelles Einzeilen-Setup verwenden

((LayoutParams) cvHolder.getLayoutParams()).setMargins(0, 0, 0, 0);

seien Sie jedoch vorsichtig, wenn Sie LayoutParams falsch verwenden, da dies keine if-Anweisungsinstanz gibt

1
Dasser Basyouni

In meinem Beispiel füge ich einem LinearLayout programmgesteuert ein ImageView hinzu. Ich habe den oberen und unteren Rand von ImagerView festgelegt. Fügen Sie dann die ImageView zum LinearLayout hinzu.



        ImageView imageView = new ImageView(mContext);
        imageView.setImageBitmap(bitmap);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT
        );
        params.setMargins(0, 20, 0, 40);
        imageView.setLayoutParams(params);
        linearLayout.addView(imageView);

0
Rajeev

Es wurde eine Kotlin-Erweiterungsfunktion für diejenigen unter Ihnen erstellt, die es vielleicht nützlich finden.

Stellen Sie sicher, dass Sie Pixel eingeben, die nicht dp sind. Fröhliches Codieren :)

fun View.addLayoutMargins(left: Int? = null, top: Int? = null,
                      right: Int? = null, bottom: Int? = null) {
    this.layoutParams = ViewGroup.MarginLayoutParams(this.layoutParams)
            .apply {
                left?.let { leftMargin = it }
                top?.let { topMargin = it }
                right?.let { rightMargin = it }
                bottom?.let { bottomMargin = it }
            }
}
0
David Kim

Sie können diese Methode verwenden und statische Dimensionen wie 20 setzen, die es entsprechend Ihrem Gerät konvertiert

 public static int dpToPx(int dp) 
      {
          float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
  }
0
Dishant Kawatra

Wie heute ist es wahrscheinlich am besten, die von AirBnB bereitgestellte Bibliothek Paris zu verwenden. 

Styles können dann wie folgt angewendet werden:

Paris.style(myView).apply(R.style.MyStyle);

es unterstützt auch die benutzerdefinierte Ansicht (wenn Sie eine Ansicht erweitern) mithilfe von Anmerkungen:

@Styleable and @Style
0
sonique

Aktualisierte:

So wie Sie früher die Breite und Höhe des Layouts mit ViewGroup.LayoutParams eingestellt haben

Sie können ViewGroup.MarginLayoutParams verwenden, um Breite, Höhe und Ränder einzustellen, ziemlich selbsterklärend, oder?

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
marginLayoutParams.setMargins(0,16,0,16);
linearLayout.setLayoutParams(marginLayoutParams);

Wobei die Methode setMargins(); Werte für left, top, right, bottom akzeptiert. Im Uhrzeigersinn !, beginnend von links.

0
mmmcho

Verwenden Sie diese Methode, um den Rand in dp einzustellen

private void setMargins (View view, int left, int top, int right, int bottom) {
    if (view.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
        ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) view.getLayoutParams();

        final float scale = getBaseContext().getResources().getDisplayMetrics().density;
        // convert the DP into pixel
        int l =  (int)(left * scale + 0.5f);
        int r =  (int)(right * scale + 0.5f);
        int t =  (int)(top * scale + 0.5f);
        int b =  (int)(bottom * scale + 0.5f);

        p.setMargins(l, t, r, b);
        view.requestLayout();
    }
}

rufen Sie die Methode auf:

setMargins(linearLayout,5,0,5,0);
0
((FrameLayout.LayoutParams) linearLayout.getLayoutParams()).setMargins(450, 20, 0, 250);
        linearLayout.setBackgroundResource(R.drawable.smartlight_background);

Ich musste meins in FrameLayout für ein linearesLayout umwandeln, da es davon erbt und dort Ränder setzt, sodass die Aktivität nur auf einem Teil des Bildschirms mit einem anderen Hintergrund als den ursprünglichen Layoutparametern in setContentView angezeigt wird. 

LinearLayout linearLayout = (LinearLayout) findViewById(R.id.activity);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(WindowManager.LayoutParams.FILL_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
linearLayout.setBackgroundColor(getResources().getColor(R.color.full_white));
setContentView(linearLayout,layoutParams);

Keiner der anderen hat dafür gearbeitet, dieselbe Aktivität zu verwenden und die Ränder basierend auf dem Öffnen der Aktivität aus einem anderen Menü zu ändern! setLayoutParams hat für mich nie funktioniert - das Gerät würde jedes Mal abstürzen. Auch wenn es sich hierbei um fest codierte Zahlen handelt - dies ist nur ein Beispiel des Codes nur zu Demonstrationszwecken. 

0
ali mcnamara