Establecer márgenes en un LinearLayout mediante programación

Estoy tratando de usar Java (no XML) para crear un LinearLayout con botones que llenen la pantalla y tengan márgenes. Aquí hay un código que funciona sin márgenes:

LinearLayout buttonsView = new LinearLayout(this);
buttonsView.setOrientation(LinearLayout.VERTICAL);
for (int r = 0; r < 6; ++r) {
    Button btn = new Button(this);
    btn.setText("A");

    LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); // Verbose!
    lp.weight = 1.0f; // This is critical. Doesn't work without it.
    buttonsView.addView(btn, lp);
}

ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
setContentView(buttonsView, lp);

Entonces eso funciona bien, pero ¿cómo diablos le da a los botones márgenes para que haya espacio entre ellos? Intenté usar LinearLayout.MarginLayoutParams, pero eso no tiene weight miembro por lo que no es bueno. Y no funciona si lo pasas lp en su constructor tampoco.

¿Es esto imposible? Porque seguro que lo parece, y no sería la primera tarea de diseño de Android que solo puede hacer en XML.

preguntado el 19 de marzo de 10 a las 22:03

desarrollador.android.com/reference/android/view/…, int, int, int) En lugar de layoutParams.setMargins (30, 20, 30, 0); pones layoutParams.setMargins (30dp, 20dp, 30dp, 0dp); -

setMargins toma int como argumentos ... solo puede proporcionar "dp" usando atributos xml -

10 Respuestas

Aquí hay un pequeño código para lograrlo:

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);

LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
     LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);

layoutParams.setMargins(30, 20, 30, 0);

Button okButton=new Button(this);
okButton.setText("some text");
ll.addView(okButton, layoutParams);

Respondido 06 Jul 15, 19:07

gracias por una muestra de código al punto, mucho más beneficioso que solo descripciones Alguien en alguna parte

Parece que los parámetros de los márgenes se establecen en píxeles. ¿Alguna forma de configurarlos en dps? - Artem Russakovskii

@ArtemRussakovskii Como la mayoría de las funciones de Android, toman píxeles. Sugiero una función de utilidad global que convierte las caídas en px. Esto es lo que he hecho en todas mis aplicaciones. La API de Android apesta. - mxcl

@MaxHowell Eso es lo que terminé haciendo. Es increíble que a veces falten cosas básicas como esa. - Artem Russakovskii

@ArtemRussakovskii - use TypedValue.applyDimension (...) para convertir DIP a PX. Ver stackoverflow.com/questions/2238883/… - Gautam

Así que eso funciona bien, pero ¿cómo diablos le da márgenes a los botones para que haya espacio entre ellos?

Llama setMargins() en el LinearLayout.LayoutParams objeto.

Intenté usar LinearLayout.MarginLayoutParams, pero no tiene un miembro de peso, por lo que no es bueno.

LinearLayout.LayoutParams es una subclase de LinearLayout.MarginLayoutParams, como se indica en el documentación.

Es esto imposible?

No.

no sería la primera tarea de diseño de Android que solo puede hacer en XML

Le invitamos a proporcionar una prueba de esta afirmación.

Personalmente, no tengo conocimiento de nada que solo se pueda lograr a través de XML y no a través de métodos Java en el SDK. De hecho, por definición, todo tiene que ser factible a través de Java (aunque no necesariamente a través de métodos accesibles al SDK), ya que XML no es un código ejecutable. Pero, si está al tanto de algo, indíquelo, porque es un error en el SDK que debería solucionarse algún día.

respondido 20 mar '10, 01:03

Ha, ok, ahora lo entiendo. Se estaba perdiendo un poco en el sistema de diseño que es bastante complicado. No creo que haya ninguna forma de establecer layout_widgth / height en tiempo de ejecución. - timmmm

Y no hay forma de establecer el estilo: stackoverflow.com/questions/2016249/… - timmmm

No he tenido ningún problema con la configuración de ancho y alto en tiempo de ejecución a través de LayoutPararms. En términos de estilos ... sí, bueno, hay una razón por la que no los uso. :-) - CommonsWare

Quiero saber por qué es un PITA generar una interfaz de usuario mediante programación. Alguien en alguna parte

Me tomó años darme cuenta de que, de hecho, hace unos días importé los LayoutParams incorrectos que no admitían Márgenes ... Al leer estas respuestas, decidí eliminar mi importación. Hay más de 10 opciones D: elegí linearLayout.LayoutParams. Obras. - soyGroot

Para agregar márgenes directamente a los elementos (algunos elementos permiten la edición directa de los márgenes), puede hacer lo siguiente:

LayoutParams lp = ((ViewGroup) something).getLayoutParams();
if( lp instanceof MarginLayoutParams )
{
    ((MarginLayoutParams) lp).topMargin = ...;
    ((MarginLayoutParams) lp).leftMargin = ...;
    //... etc
}
else
    Log.e("MyApp", "Attempted to set the margins on a class that doesn't support margins: "+something.getClass().getName() );

... esto funciona sin necesidad de conocer / editar el diseño circundante. Tenga en cuenta la marca "instancia de" en caso de que intente ejecutar esto contra algo que no admite márgenes.

contestado el 09 de mayo de 13 a las 12:05

Es exactamente lo que estoy buscando. - djdance

Debido a la variación en la densidad de píxeles de la pantalla del dispositivo, es bueno usarlo siempre DIP unidad para establecer el margen mediante programación. Como abajo_

//get resources
Resources r = getResources();
float pxLeftMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxTopMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxRightMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, r.getDisplayMetrics());
float pxBottomMargin = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());

//get layout params...
LayoutParams params=new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
params.setMargins(Math.round(pxLeftMargin), Math.round(pxTopMargin), Math.round(pxRightMargin), Math.round(pxBottomMargin));

//set margin...
yourLayoutTOsetMargin.setLayoutParams(params); 

Espero que esto ayude.

Respondido el 09 de junio de 14 a las 14:06

He configurado márgenes directamente usando el siguiente código

LinearLayout layout = (LinearLayout)findViewById(R.id.yourrelative_layout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.WRAP_CONTENT);            
params.setMargins(3, 300, 3, 3); 
layout.setLayoutParams(params);

Lo único aquí es notar que LayoutParams debe importarse para el siguiente paquete android.widget.RelativeLayout.LayoutParams, de lo contrario habrá un error.

Respondido el 17 de Septiembre de 15 a las 09:09

 MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();
 layoutParams.setMargins(leftMargin, topMargin, rightMargin, bottomMargin);

Respondido 20 Oct 16, 02:10

“Si bien este código puede responder a la pregunta, es mejor incluir la explicación del código aquí. - xenteros

Prueba esta

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

Respondido 07 Oct 13, 10:10

Prueba esto:

MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;

Respondido 26 Abr '17, 06:04

/*
 * invalid margin
 */
private void invalidMarginBottom() {
    RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) frameLayoutContent.getLayoutParams();
    lp.setMargins(0, 0, 0, 0);
    frameLayoutContent.setLayoutParams(lp);
}

debe tener en cuenta el tipo de viewGroup de la vista. En el código anterior, por ejemplo, quiero cambiar el margen de frameLayout, y el grupo de vista de frameLayout es un Disposición relativa, Por lo que debes convertirte en (RelativeLayout.LayoutParams)

contestado el 06 de mayo de 15 a las 10:05

Aquí una solución de una sola línea:

((LinearLayout.LayoutParams) yourLinearLayout.getLayoutParams()).marginToAdd = ((int)(Resources.getSystem().getDisplayMetrics().density * yourDPValue));

Respondido 19 Abr '17, 12:04

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.