Jak ustawić margines ImageView za pomocą kodu, a nie XML


177

Chcę dodać nieznaną liczbę ImageViewwidoków do mojego układu z marginesami. W XML mogę użyć w layout_marginten sposób:

<ImageView android:layout_margin="5dip" android:src="@drawable/image" />

Jest ImageView.setPadding(), ale nie ImageView.setMargin(). Myślę, że jest to podobne ImageView.setLayoutParams(LayoutParams), ale nie jestem pewien, czym się w to karmić.

Czy ktoś wie?

Odpowiedzi:


381

android.view.ViewGroup.MarginLayoutParamsma metodę setMargins(left, top, right, bottom). Bezpośrednie podklasy to: FrameLayout.LayoutParams, LinearLayout.LayoutParamsi RelativeLayout.LayoutParams.

Używając np LinearLayout:

LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(left, top, right, bottom);
imageView.setLayoutParams(lp);

MarginLayoutParams

To ustawia marginesy w pikselach. Aby go skalować, użyj

context.getResources().getDisplayMetrics().density

DisplayMetrics


18
Zauważ, że to ustawia rozmiar marginesów w PIKSELACH, nie jest tym samym, co jednostka dpi w xml tego pytania.
aromero

Jak możemy użyć wartości dpi zamiast piksela?
Pascal Piché

10
Możesz skalować wartość w pikselach za pomocą context.getResources (). GetDisplayMetrics (). Density developer.android.com/reference/android/util/ ...
Klucz

1
Zauważ, że mogą być problemy z FrameLayout.LayoutParamsinnymi: stackoverflow.com/questions/5401952/…
Dmitry Zaytsev

na wypadek, gdybyśmy chcieli ustawić tylko dolny margines widoku obrazu, który jest android:layout_centerHorizontal = "true"iw android:layout_alignParentBottom = "true"jaki sposób mógłbym to osiągnąć?
ssrp

51
    image = (ImageView) findViewById(R.id.imageID);
    MarginLayoutParams marginParams = new MarginLayoutParams(image.getLayoutParams());
    marginParams.setMargins(left_margin, top_margin, right_margin, bottom_margin);
    RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
    image.setLayoutParams(layoutParams);

5
O co chodzi w ostatnich 2 liniach? sklonować parametry marginesu do innej zmiennej params? Potwierdzam, że jest to wymagane :)
Adam Rabung

1
na wypadek, gdybyśmy chcieli ustawić tylko dolny margines widoku obrazu, który jest android:layout_centerHorizontal = "true"iw android:layout_alignParentBottom = "true"jaki sposób mógłbym to osiągnąć?
ssrp

layoutparams.addRule (RelativeLayout.CENTER_HORIZONTAL);
cwhsu

Wymagane jest utworzenie innych parametrów układu. Dzięki :)
Muzaffer

42

Wszystkie powyższe przykłady faktycznie ZMIENI wszelkie parametry już obecne w Widoku, co może nie być pożądane. Poniższy kod po prostu rozszerzy istniejące parametry, bez ich zastępowania:

ImageView myImage = (ImageView) findViewById(R.id.image_view);
MarginLayoutParams marginParams = (MarginLayoutParams) image.getLayoutParams();
marginParams.setMargins(left, top, right, bottom);

1
To pierwsze rozwiązanie na tej liście, które zadziałało dla mnie. Inni schrzanili inne parametry, które ustawiłem w XML, w tym parametry RelativeLayout do pozycjonowania.
Chris Dutrow

22

Kod Kevina tworzy nadmiarowy MarginLayoutParamsobiekt. Prostsza wersja:

ImageView image = (ImageView) findViewById(R.id.main_image);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(image.getLayoutParams());
lp.setMargins(50, 100, 0, 0);
image.setLayoutParams(lp);

1
Co dziwne, otrzymuję wtedy komunikat „Cannot rozwiązać metodę setmargins ()”, dlatego wyszukałem w Google to pytanie i wylądowałem tutaj.
user2875404

11

Jeśli chcesz zmienić margines widoku obrazu, ale pozostałe marginesy pozostaw nienaruszone.

  1. Pobierz MarginLayoutParameters widoku obrazu w tym przypadku: myImageView

     MarginLayoutParams marginParams = (MarginLayoutParams) myImageView.getLayoutParams();
  2. Teraz po prostu zmień margines, który chcesz zmienić, ale pozostałe pozostaw bez zmian:

     marginParams.setMargins(marginParams.leftMargin, 
                             marginParams.topMargin, 
                             150, //notice only changing right margin
                             marginParams.bottomMargin); 

8

Możesz użyć tej metody, jeśli chcesz określić marginesy w dp:

private void addMarginsInDp(View view, int leftInDp, int topInDp, int rightInDp, int bottomInDp) {
    DisplayMetrics dm = view.getResources().getDisplayMetrics();
    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    lp.setMargins(convertDpToPx(leftInDp, dm), convertDpToPx(topInDp, dm), convertDpToPx(rightInDp, dm), convertDpToPx(bottomInDp, dm));
    view.setLayoutParams(lp);
}

private int convertDpToPx(int dp, DisplayMetrics displayMetrics) {
    float pixels = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
    return Math.round(pixels);
}

8

Używam po prostu tego i działa świetnie:

ImageView imageView = (ImageView) findViewById(R.id.image_id);
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) imageView.getLayoutParams();
layoutParams.setMargins(left, top, right, bottom);
imageView.setLayoutParams(layoutParams);

Jednostką setMargins () jest piksel, a nie dp. Jeśli chcesz ustawić margines w dp, po prostu w pliku values ​​/ dimens.xml utwórz wymiary takie jak:

<resources>
    <dimen name="right">16dp</dimen>
    <dimen name="left">16dp</dimen>    
</resources>

i dostęp jak:

getResources().getDimension(R.dimen.right);

5

Jeśli używasz kotlin, można to uprościć, tworząc funkcję rozszerzającą

fun View.setMarginExtensionFunction(left: Int, top: Int, right: Int, bottom: Int) {
  val params = layoutParams as ViewGroup.MarginLayoutParams
  params.setMargins(left, top, right, bottom)
  layoutParams = params
}

Teraz wszystko, czego potrzebujesz, to widok, a tej funkcji rozszerzenia można używać w dowolnym miejscu.

val imageView = findViewById(R.id.imageView)
imageView.setMarginExtensionFunction(0, 0, 0, 0)

1
działa to dla marginesów lefti right, ale jeśli masz marginesy względne ( starti end), to nie działa. Napisałem streszczenie z „ulepszoną” wersją Twojego kodu: gist.github.com/Grohden/f40c53bf86c5395638f7a44bf90e732d ( setMarginsRelativefunkcja) - czy możesz uwzględnić to w swojej odpowiedzi?
Gabriel De Oliveira Rohden

4

utwórz układ dynamicznie i ustaw jego parametr jako setmargin () nie będzie działać bezpośrednio na imageView

ImageView im;
im = (ImageView) findViewById(R.id.your_image_in_XML_by_id);
 RelativeLayout.LayoutParams layout = new RelativeLayout.LayoutParams(im.getLayoutParams());
                        layout.setMargins(counter*27, 0, 0, 0);//left,right,top,bottom
                        im.setLayoutParams(layout);
                        im.setImageResource(R.drawable.yourimage)

4

U mnie to zadziałało:

int imgCarMarginRightPx = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, definedValueInDp, res.getDisplayMetrics());

MarginLayoutParams lp = (MarginLayoutParams) imgCar.getLayoutParams();
lp.setMargins(0,0,imgCarMarginRightPx,0);
imgCar.setLayoutParams(lp);

2

przykładowy kod jest tutaj, jest bardzo łatwy

LayoutParams params1 = (LayoutParams)twoLetter.getLayoutParams();//twoletter-imageview
                params1.height = 70;
                params1.setMargins(0, 210, 0, 0);//top margin -210 here
                twoLetter.setLayoutParams(params1);//setting layout params
                twoLetter.setImageResource(R.drawable.oo);

0

Użycie metody podobnej do tej może w niektórych sytuacjach oszczędzić Ci bólu głowy. Jeśli masz dwa przebiegi programowego majstrowania przy marginesach, bezpieczniej jest sprawdzić, czy są już ustawione parametry layoutParams. Jeśli są już jakieś marże, to należy je zwiększyć, a nie zastępować:

public void addMargins(View v, int left, int top, int right, int bottom) {
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
    if (params == null)
        params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
                                               ViewGroup.LayoutParams.WRAP_CONTENT);
    int oldLeft = params.leftMargin;
    int oldTop = params.topMargin;
    int oldRight = params.rightMargin;
    int oldBottom = params.bottomMargin;
    params.setMargins(oldLeft + left, oldTop + top, oldRight + right, oldBottom + bottom);
    v.setLayoutParams(params);
}

0

Oto przykład dodania marginesu 8px po lewej, górnej, prawej i dolnej stronie.


ImageView imageView = new ImageView(getApplicationContext());

ViewGroup.MarginLayoutParams marginLayoutParams = new ViewGroup.MarginLayoutParams(
    ViewGroup.MarginLayoutParams.MATCH_PARENT,
    ViewGroup.MarginLayoutParams.WRAP_CONTENT
);

marginLayoutParams.setMargins(8, 8, 8, 8);

imageView.setLayoutParams(marginLayoutParams);

0

Odpowiedź z 2020 roku:

dependencies {
    implementation "androidx.core:core-ktx:1.2.0"
}

i wywołaj go po prostu w swoim kodzie

view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
   setMargins(5)
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.