¿Cómo puedo obtener un Android TableLayout para llenar la pantalla?

Estoy luchando con el horrible sistema de diseño de Android. Estoy tratando de obtener una tabla para llenar la pantalla (¿verdad?) Pero es ridículamente difícil.

Lo tengo para trabajar de alguna manera en XML de esta manera:

   

Sin embargo, no puedo hacer que funcione en Java. He probado un millón de combinaciones de los LayoutParams, pero nada funciona. Este es el mejor resultado que tengo, que solo llena el ancho de la pantalla, no la altura:

  table = new TableLayout(this); // Java. You suck. TableLayout.LayoutParams lp = new TableLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); table.setLayoutParams(lp); // This line has no effect! WHYYYY?! table.setStretchAllColumns(true); for (int r = 0; r < 2; ++r) { TableRow row = new TableRow(this); for (int c = 0; c < 2; ++c) { Button btn = new Button(this); btn.setText("A"); row.addView(btn); } table.addView(row); } 

Obviamente la documentación de Android no sirve de nada. ¿Alguien tiene alguna idea?

Hay dos errores en la discusión anterior.

  1. Es posible establecer el peso TableLayout.LayoutParams especificando TableLayout.LayoutParams y TableRow.LayoutParams y usando el constructor apropiado, por ejemplo

     TableLayout.LayoutParams rowInTableLp = new TableLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT, 1.0f); 
  2. Un widget debe tener los LayoutParams de su padre. Por lo tanto, las filas deben usar TableLayout.LayoutParams .

Esto le da la siguiente versión de trabajo de su código inicial:

 TableLayout table = new TableLayout(this); // Java. You succeed! FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); table.setLayoutParams(lp); table.setStretchAllColumns(true); TableLayout.LayoutParams rowLp = new TableLayout.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT, 1.0f); TableRow.LayoutParams cellLp = new TableRow.LayoutParams( ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT, 1.0f); for (int r = 0; r < 2; ++r) { TableRow row = new TableRow(this); for (int c = 0; c < 2; ++c) { Button btn = new Button(this); btn.setText("A"); row.addView(btn, cellLp); } table.addView(row, rowLp); } setContentView(table); 

Gracias al comentario de Romain Guy en el foro de desarrolladores de Android para la solución .

Finalmente resolvió cómo hacer esto. TableLayout a TableLayout y solo usé LinearLayout horizontal dentro de uno vertical. La clave crítica es establecer el peso. Si especifica FILL_PARENT pero con el peso predeterminado, no funciona:

 LinearLayout buttonsView = new LinearLayout(this); buttonsView.setOrientation(LinearLayout.VERTICAL); for (int r = 0; r < 6; ++r) { LinearLayout row = new LinearLayout(this); row.setOrientation(LinearLayout.HORIZONTAL); for (int c = 0; c < 4; ++c) { Button btn = new Button(this); btn.setText("A"); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); lp.weight = 1.0f; row.addView(btn, lp); } LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT); lp.weight = 1.0f; buttonsView.addView(row, lp); } ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT); setContentView(buttonsView, lp); 

Encontré la respuesta: al parecer, es el layout_weight el que lo hace funcionar y no hay forma de configurarlo desde Java. Maldición.

Consulte ¿Cómo puedo obtener un TableLayout de Android para llenar el padre en modo horizontal?

Nunca establece los parámetros de diseño de la fila o el botón, mientras que en el xml publicado lo hace … cambie los detalles de los bucles for para establecer tanto los parámetros de diseño de la fila como los parámetros del diseño del botón que deberían dar el mismo resultado que su xml.

Para establecer TableLayout LayoutParams, lógicamente esperamos utilizar la clase TableLayout.LayoutParams, pero obtendrá un error de conversión que indica que TableLayout.LayoutParams no se puede convertir en FrameLayout.LayoutParams.

Por lo tanto, debe usar FrameLayout.LayoutParams, si desea establecer programáticamente las propiedades de TableLayout. Por ejemplo:

 FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,TableLayout.LayoutParams.MATCH_PARENT); layoutParams.setMargins(80, 0, 0, 0); TableLayout tableLayout = (TableLayout) findViewById(R.id.header_detail); tableLayout.setLayoutParams(layoutParams);