Cómo establecer el margen de ImageView usando código, no xml

177

Quiero agregar un número desconocido de ImageViewvistas a mi diseño con margen. En XML, puedo usar layout_marginasí:

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

Hay ImageView.setPadding(), pero no ImageView.setMargin(). Creo que está en la línea de ImageView.setLayoutParams(LayoutParams), pero no estoy seguro de qué alimentar con eso.

¿Alguien sabe?

Bruce Lee
fuente

Respuestas:

381

android.view.ViewGroup.MarginLayoutParamsTiene un método setMargins(left, top, right, bottom). Subclases directas son: FrameLayout.LayoutParams, LinearLayout.LayoutParamsy RelativeLayout.LayoutParams.

Usando, por ejemplo 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

Esto establece los márgenes en píxeles. Para escalarlo use

context.getResources().getDisplayMetrics().density

DisplayMetrics

Llave
fuente
18
Tenga en cuenta que esto establece el tamaño del margen en PIXELS, no es lo mismo que la unidad de dpi en el xml de esta pregunta.
aromero el
¿Cómo podemos usar un valor de dpi en lugar de píxeles?
Pascal Piché
10
Puede escalar el valor de px usando context.getResources (). GetDisplayMetrics (). Density developer.android.com/reference/android/util/…
Key
1
Tenga en cuenta que puede haber problemas FrameLayout.LayoutParamsy tal vez con otros: stackoverflow.com/questions/5401952/…
Dmitry Zaytsev
en caso de que queríamos establecer sólo el margen inferior de la vista de la imagen que es android:layout_centerHorizontal = "true"y android:layout_alignParentBottom = "true"en forma waht pude lograr esto?
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);
Kevin Wadera
fuente
55
¿Cuál es el trato con las últimas 2 líneas? clonar los parámetros de margen en otra variable de parámetros? Puedo confirmar que es obligatorio :)
Adam Rabung
1
en caso de que queríamos establecer sólo el margen inferior de la vista de la imagen que es android:layout_centerHorizontal = "true"y android:layout_alignParentBottom = "true"en forma waht pude lograr esto?
ssrp
layoutparams.addRule (RelativeLayout.CENTER_HORIZONTAL);
cwhsu
Se requiere crear otros parámetros de diseño. Gracias :)
Muzaffer
42

Todos los ejemplos anteriores REEMPLAZARÁN cualquier parámetro ya presente para la Vista, que puede no ser deseado. El siguiente código solo extenderá los parámetros existentes, sin reemplazarlos:

ImageView myImage = (ImageView) findViewById(R.id.image_view);
MarginLayoutParams marginParams = (MarginLayoutParams) image.getLayoutParams();
marginParams.setMargins(left, top, right, bottom);
Kelevandos
fuente
1
Esta es la primera solución en esta lista que funcionó para mí. Los otros arruinaron los otros parámetros que había establecido en el XML, incluidos los parámetros RelativeLayout para el posicionamiento.
Chris Dutrow
22

El código de Kevin crea MarginLayoutParamsobjetos redundantes . Versión más simple:

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);
Adam Stelmaszczyk
fuente
1
Por extraño que parezca, aparece "No se puede resolver el método setmargins ()", por lo que busqué en Google esta pregunta y llegué aquí.
usuario2875404
11

Si desea cambiar el margen de vista de la imagen pero dejar todos los demás márgenes intactos.

  1. Obtenga MarginLayoutParameters de su vista de imagen en este caso: myImageView

     MarginLayoutParams marginParams = (MarginLayoutParams) myImageView.getLayoutParams();
  2. Ahora solo cambie el margen que desea cambiar, pero deje los demás como están:

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

Puede usar este método, en caso de que desee especificar márgenes en 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);
}
divonas
fuente
8

Simplemente uso esto y funciona muy bien:

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

La unidad de setMargins () es pixel no dp. Si desea establecer el margen en dp, solo dentro de su archivo values ​​/ dimens.xml cree sus dimensiones como:

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

y acceda como:

getResources().getDimension(R.dimen.right);
Elnoor
fuente
5

Si usa kotlin, esto se puede simplificar creando una función de extensión

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
}

Ahora todo lo que necesita es una vista, y esta función de extensión se puede usar en cualquier lugar.

val imageView = findViewById(R.id.imageView)
imageView.setMarginExtensionFunction(0, 0, 0, 0)
enyciaa
fuente
1
esto funciona para lefty rightmárgenes, pero si tiene márgenes relativos ( starty end) no funciona. Escribí un resumen con una versión 'mejorada' de su código: gist.github.com/Grohden/f40c53bf86c5395638f7a44bf90e732d (la setMarginsRelativefunción), ¿podría incluir eso en su respuesta?
Gabriel De Oliveira Rohden
4

crear un diseño de forma dinámica y establecer su parámetro como setmargin () no funcionará directamente en una 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)
Muhammad Adil
fuente
4

Para mí esto funcionó:

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);
Wahib Ul Haq
fuente
2

el código de muestra está aquí, es muy fácil

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);
Sydroid
fuente
0

Usar un método similar a este podría ahorrarle dolores de cabeza en algunas situaciones. Si tiene dos pases de retoques programáticos con márgenes, es más seguro verificar si ya hay algún conjunto de parámetros de diseño. Si ya hay algunos márgenes, uno debería aumentarlos y no reemplazarlos:

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);
}
GA1
fuente
0

Aquí hay un ejemplo para agregar un margen de 8px a la izquierda, arriba, derecha, abajo.


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);
MD Zubaer Ahammed
fuente
0

Respuesta del año 2020:

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

y califícalo simplemente en tu código

view.updateLayoutParams<ViewGroup.MarginLayoutParams> {
   setMargins(5)
}
i30mb1
fuente