Establecer márgenes en un LinearLayout mediante programación
Frecuentes
Visto 356,088 equipos
277
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.
10 Respuestas
509
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 Rusakovskii
@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 Rusakovskii
@ArtemRussakovskii - use TypedValue.applyDimension (...) para convertir DIP a PX. Ver stackoverflow.com/questions/2238883/… - Gautam
64
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 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. :-) - Artículos comunes
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
31
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. - djbaile
22
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
10
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
7
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
4
Prueba esto:
MarginLayoutParams params = (MarginLayoutParams) view.getLayoutParams();
params.width = 250;
params.leftMargin = 50;
params.topMargin = 50;
Respondido 26 Abr '17, 06:04
3
/*
* 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
0
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
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); - DarthestVader
setMargins toma int como argumentos ... solo puede proporcionar "dp" usando atributos xml - jyavenard