Android'de, dp'deki kenar boşluklarını program aracılığıyla nasıl ayarlarım?


401

Gelen bu , bu ve bu iş parçacığı tek bir görünümde kenar boşluklarını ayarlamak için nasıl bir cevap bulmaya çalıştık. Ancak, daha kolay bir yol olup olmadığını merak ediyordum. Neden bu yaklaşımı kullanmak istemediğimi açıklayacağım:

Düğme genişleten özel bir Düğme var. Arka plan, varsayılan arka plan dışında başka bir şeye ayarlanırsa ( setBackgroundResource(int id)veya birini çağırarak setBackgroundDrawable(Drawable d)), kenar boşluklarının 0 olmasını isterim.

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

Kenar boşluklarını -3dp'ye sıfırlamak istiyorum ( Burada piksellerden dp'ye nasıl dönüştürüleceğini zaten okudum , bu yüzden pikselde kenar boşluklarını nasıl ayarlayacağımı bildiğimde, dönüşümü kendim yönetebilirim). Ancak bu CustomButtonsınıfta çağrıldığından , üst öğe LinearLayout'tan TableLayout'a kadar değişebilir ve onun ebeveynini almasını ve o ebeveynin örneğini kontrol etmesini istemem. Bu da oldukça sağlam olacak, sanırım.

Ayrıca, (LayoutParams kullanarak) çağrılırken parentLayout.addView(myCustomButton, newParams), bu doğru konuma ekleyip eklemediğini bilmiyorum (ancak denemedim), beş satırın orta düğmesini söyleyin.

Soru: LayoutParams'ı kullanmanın yanı sıra tek bir Düğmenin kenar boşluğunu programlı olarak ayarlamanın daha kolay bir yolu var mı ?

DÜZENLEME: LayoutParams yolunu biliyorum, ancak her farklı kap türünü işlemekten kaçınan bir çözüm istiyorum:

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

Çünkü this.getLayoutParams();getiri Bir ViewGroup.LayoutParamsözelliklerini yok topMargin, bottomMargin, leftMargin, rightMargin. Gördüğünüz mc örneği, yalnızca MarginContainerofset (-3dp) kenar boşlukları ve (oml, omr, omt, omb) ve orijinal kenar boşluklarını (ml, mr, mt, mb) içeren bir alandır.

Yanıtlar:


797

LayoutParamsDüğme kenar boşluklarınızı ayarlamak için şunu kullanmalısınız :

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

Hangi düzeni kullandığınıza bağlı olarak RelativeLayout.LayoutParamsveya seçeneğini kullanmalısınız LinearLayout.LayoutParams.

Ve dp ölçünüzü piksele dönüştürmek için şunu deneyin:

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

152
Bu belirli LayoutParams'ı hangi paketten içe aktarmalıyım?
stealthjong

7
setMargins px kullanıyor ve dp kullanacaksınız, dönüşümüm doğru: dp -> px doğru kenar boşluğu değerini ayarlamak için.
throrin19

6
@ChristiaandeJong RelativeLayout.LayoutParams
stoefln

15
mevcut düzeninize bağlıdır. LinearLayout'taysanız, LinearLayout.LayoutParams kullanın.
Başka

5
üst mizanpajınız olan layoutParams'ı içe aktarmanız gerekir. <linearlayout><relativelayout> <gridlayout> ve ızgara düzeniyle çalışıyorsunuz. sonra, relativelayout.layoutparams
Sruit A.Suk

228

LayoutParams - ÇALIŞMIYOR! ! !

Kullanmanız gereken tür: MarginLayoutParams

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

MarginLayoutParams için Kod Örneği:

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


19
Doğru, ancak geri koymaya gerek yok, değiştirilen parametreler otomatik olarak yansıtılır. Böylece satırı kaldırabilirsiniz: vector8.setLayoutParams (params);
Wirsing

LayaoutParams genellikle kenar boşluğu ayarlarken karışıklık yaratır ... Bu nedenle bu MarginLayoutParams çok kullanışlıdır. Teşekkürler
Atul Bhardwaj

4
marging değişikliklerinden sonra LayoutParams (params) ayarlamanız gerekiyor
Leo Droidcoder

Bugün #Thanks yeni sınıf olarak MarginLayoutParams buldum.
Tushar Pandey

Görüntüleme için çalışmıyor Button: ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) button.getLayoutParams()dönernull
Konstantin Konopko

118

Şimdiye kadarki en iyi yol:

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

Arama yöntemi:

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

Umarım bu size yardımcı olacaktır.


1
setMargins (holder.vCenter, 0, 20, 0,0) ayarladığımda sorunla karşılaşıyorum ; Bu şekilde izin kenarları her iki tarafta (üst ve alt) yukarıdaki parametrelerle yanlış olan nedir?
2018

1
Müthiş mükemmel cevap !! Teşekkür ederim!!
Sjd

33
int sizeInDP = 16;

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

Sonra

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

Veya

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

15

İşte son güncellemelerle hepsi bir arada cevap:

1. adım, marjı güncellemek için

Temel fikir, marjın dışarı çıkıp güncellenmesidir. Güncelleme otomatik olarak uygulanacaktır ve geri ayarlamanıza gerek yoktur. Düzen parametrelerini almak için şu yöntemi çağırmanız yeterlidir:

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

LayoutParamsSenin bakış düzeni geliyor. Görünüm doğrusal bir mizanpajdaysa, içe aktarmanız gerekir LinearLayout.LayoutParams. Göreli düzen, içe aktarma LinearLayout.LayoutParamsvb. Kullanıyorsanız

Eğer kullanarak marjı ayarlamak Şimdi, eğer Layout_marginLeft, Rightvb, bu şekilde güncelleme marjı gerekir

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

Kenar boşluğunu yeniyi kullanarak ayarlarsanız, kenar layout_marginStartboşluğunu bu şekilde güncellemeniz gerekir

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

Adım 2, dp'de kenar boşluğunu güncellemek için

Yukarıdaki kenar boşluğunu güncellemenin iki yolu da piksel olarak güncellenir. Dp to pixels 'nin bir çevirisini yapmalısınız.

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

Şimdi hesaplanan değeri yukarıdaki kenar boşluğu güncelleme işlevlerine koyun ve hepiniz ayarlanmış olmalısınız


9

layout_margin, bir görünüm alt öğesinin üst öğesine bildirdiği bir kısıtlamadır. Ancak, marja izin verip vermemeyi seçmek ebeveynin rolüdür. Temel olarak android: layout_margin = "10dp" ayarlanarak, ana boyut grubuna gerçek boyutundan 10dp daha büyük alan ayırması için yalvarıyor . (dolgu = "10dp", diğer yandan, çocuk görünümünün kendi içeriğini 10dp daha küçük yapacağını gösterir .)

Sonuç olarak, tüm ViewGroup'lar marja saygı göstermez . En kötü şöhretli örnek, öğelerin kenar boşluklarının göz ardı edildiği liste görünümüdür. setMargin()Bir LayoutParam'ı çağırmadan önce , geçerli görünümün kenar boşluğunu (ör. LinearLayouot veya RelativeLayout) destekleyen bir ViewGroup'ta yaşadığından ve sonucunu getLayoutParams()istediğiniz belirli LayoutParams'a aktardığınızdan emin olmalısınız. ( yöntemi ViewGroup.LayoutParamsbile yok setMargins()!)

Aşağıdaki işlev hile yapmalıdır. Ancak, RelativeLayout öğesini üst görünümün türüyle değiştirdiğinizden emin olun.

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

9

Bu yöntem set izin verir Marjı içinde 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);
}

GÜNCELLEME

İhtiyacınıza uygun parametreyi değiştirebilirsiniz.


8

Kotlin'de şöyle görünecek:

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

3

Özel bir Görünüm'deyken, getDimensionPixelSize(R.dimen.dimen_value)benim durumumda, inityöntemi kullanarak oluşturulan LayoutParams'ta kenar boşluğunu ekledim .

Kotlin bölgesinde

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

Java dilinde:

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

1

Dp'de kenar boşluğunu ayarlamak için bu yöntemi kullanın

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

yöntemi çağırın:

setMargins(linearLayout,5,0,5,0);

1

Hızlı tek satırlık kurulum için

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

ancak LayoutParams için herhangi bir yanlış kullanım için dikkatli olun, çünkü bunun bir ifade iförneği yok


1

Kullanışlı bulabilecekleriniz için Kotlin Uzantısı işlevi oluşturuldu.

Dp değil piksel olarak ilettiğinizden emin olun. Mutlu kodlama :)

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

1

Benim örneğimde programlı bir LinearLayout için bir ImageView ekliyorum. ImagerView için üst ve alt kenar boşluklarını ayarladım. Daha sonra ImageView'ı LinearLayout'a ekleyin.



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

1

Bu yöntemi kullanabilir ve cihazınıza göre dönüştürdüğü gibi 20 gibi statik dimen koyabilirsiniz.

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

0

Bugüne gibi, en iyi kullanmak muhtemelen Paris , Airbnb tarafından sağlanan bir kütüphane.

Stiller daha sonra şu şekilde uygulanabilir:

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

ek açıklamaları kullanarak özel görünümü (bir görünümü genişletirseniz) destekler:

@Styleable and @Style

0

Aramak zorundasın

setPadding(int left, int top, int right, int bottom)

şöyle: your_view.setPadding(0,16,0,0)

Kullanmaya çalıştığınız şey sadece alıcı.

Android stüdyosu java'da padding...()gerçekte ne anlama geldiğini gösterir :

dolgu örneği Resimde yalnızca çağrılar gösteriliyorgetPadding...()

TextView öğenize bir kenar boşluğu eklemek istiyorsanız LayoutParams'ı kullanmanız gerekir:

val params =  LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT)
params.setMargins(int left, int top, int right, int bottom)
your_view.layoutParams = params

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

Ben FrameLayoutondan miras olarak lineerLayout için benim döküm gerekiyordu ve orada kenar boşluklarını ayarlamak böylece etkinlik sadece ekranın bir kısmında orijinal düzeni params daha farklı bir arka plan ile birlikte görünür setContentView.

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

Diğer hiçbiri, aynı etkinliği kullanmak ve etkinliği farklı bir menüden açmaya bağlı olarak kenar boşluklarını değiştirmek için çalışmadı! setLayoutParams benim için hiç çalışmadı - cihaz her seferinde çökecekti. Bunlar sabit kodlanmış sayılar olmasına rağmen - bu yalnızca gösterim amaçlı kodun sadece bir örneğidir.


-1

ViewGroup.MarginLayoutParamsGenişliği, yüksekliği ve kenar boşluklarını ayarlamak için kullanabilirsiniz

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

Yöntemin setMargins();sırasıyla sol, üst, sağ, alt için değerleri alması. Soldan başlayarak saat yönünde!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.