Saltar al contenido

Cómo hacer que un GridLayout se ajuste al tamaño de la pantalla

Después de mucho batallar ya dimos con la contestación de este contratiempo que agunos lectores de nuestro espacio han tenido. Si tienes algo más que aportar puedes aportar tu conocimiento.

Solución:

Nota: La información debajo de la línea horizontal ya no es precisa con la introducción de Android ‘Lollipop’ 5, ya que GridLayoutlo hace acomodar el principio de pesos desde API nivel 21.

Citado del Javadoc:

Distribución de espacio en exceso

A partir de API 21, la distribución del exceso de espacio de GridLayout se ajusta al principio del peso. En el caso de que no se especifiquen pesos, se respetan las convenciones anteriores y las columnas y filas se toman como flexibles si sus vistas especifican alguna forma de alineación dentro de sus grupos. Por lo tanto, la flexibilidad de una vista está influenciada por su alineación que, a su vez, se define típicamente estableciendo la propiedad de gravedad de los parámetros de diseño del niño. Si se definió un peso o una alineación a lo largo de un eje dado, el componente se considera flexible en esa dirección. Si no se estableció ningún peso o alineación, se supone que el componente es inflexible.

Se considera que varios componentes de la misma fila o grupo de columnas actúan en paralelo. Un grupo de este tipo es flexible solo si todos los componentes que lo integran son flexibles. En cambio, se considera que los grupos de filas y columnas que se encuentran a ambos lados de un límite común actúan en serie. El grupo compuesto formado por estos dos elementos es flexible si uno de sus elementos es flexible.

Para estirar una columna, asegúrese de que todos los componentes de su interior definan un peso o una gravedad. Para evitar que una columna se estire, asegúrese de que uno de los componentes de la columna no defina un peso o una gravedad.

Cuando el principio de flexibilidad no proporciona una desambiguación completa, los algoritmos de GridLayout favorecen las filas y columnas que están más cerca de sus bordes derecho e inferior. Para ser más precisos, GridLayout trata cada uno de sus parámetros de diseño como una restricción en un conjunto de variables que definen las líneas de cuadrícula a lo largo de un eje dado. Durante el diseño, GridLayout resuelve las restricciones para devolver la solución única a aquellas restricciones para las cuales todas las variables son menores o iguales al valor correspondiente en cualquier otra solución válida.

También vale la pena señalar que android.support.v7.widget.GridLayout contiene la misma información. Desafortunadamente, no menciona con qué versión de la biblioteca de soporte se introdujo, pero la confirmación que agrega la funcionalidad se puede rastrear hasta julio de 2014. En noviembre de 2014, se corrigieron las mejoras en el cálculo del peso y un error.

Para estar seguro, asegúrese de importar la última versión de la biblioteca gridlayout-v7.


El principio de ‘pesos’, como lo está describiendo, no existe con GridLayout. Esta limitación se menciona claramente en la documentación; extracto a continuación. Dicho esto, existen algunas posibilidades de utilizar la “gravedad” para la distribución del espacio en exceso. Le sugiero que haya leído la documentación vinculada.

Limitaciones

GridLayout no proporciona soporte para el principio de peso, como se define en peso. En general, por lo tanto, no es posible configurar un GridLayout para distribuir el exceso de espacio en proporciones no triviales entre múltiples filas o columnas. No obstante, algunos casos de uso comunes pueden adaptarse de la siguiente manera. Colocar cantidades iguales de espacio alrededor de un componente en un grupo de celdas; utilice alineación CENTRAL (o gravedad). Para un control completo sobre la distribución del espacio sobrante en una fila o columna; use una subvista LinearLayout para contener los componentes en el grupo de celdas asociado. Cuando utilice cualquiera de estas técnicas, tenga en cuenta que los grupos de células pueden definirse para superponerse.

Para ver un ejemplo y algunos consejos prácticos, eche un vistazo a la publicación del blog del año pasado que presenta el GridLayout widget.


Editar: No creo que haya un enfoque basado en xml para escalar los mosaicos como en la aplicación Google Play a ‘cuadrados’ o ‘rectángulos’ dos veces la longitud de esos cuadrados. Sin embargo, ciertamente es posible si crea su diseño mediante programación. Todo lo que realmente necesita saber para lograrlo son las dimensiones de la pantalla del dispositivo.

Debajo de una aproximación (¡muy!) Rápida y sucia del diseño en mosaico en la aplicación Google Play.

Point size = new Point();
getWindowManager().getDefaultDisplay().getSize(size);
int screenWidth = size.x;
int screenHeight = size.y;
int halfScreenWidth = (int)(screenWidth *0.5);
int quarterScreenWidth = (int)(halfScreenWidth * 0.5);

Spec row1 = GridLayout.spec(0, 2);
Spec row2 = GridLayout.spec(2);
Spec row3 = GridLayout.spec(3);
Spec row4 = GridLayout.spec(4, 2);

Spec col0 = GridLayout.spec(0);
Spec col1 = GridLayout.spec(1); 
Spec colspan2 = GridLayout.spec(0, 2);

GridLayout gridLayout = new GridLayout(this);
gridLayout.setColumnCount(2);
gridLayout.setRowCount(15);

TextView twoByTwo1 = new TextView(this);
GridLayout.LayoutParams first = new GridLayout.LayoutParams(row1, colspan2);
first.width = screenWidth;
first.height = quarterScreenWidth * 2;
twoByTwo1.setLayoutParams(first);
twoByTwo1.setGravity(Gravity.CENTER);
twoByTwo1.setBackgroundColor(Color.RED);
twoByTwo1.setText("TOP");
twoByTwo1.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByTwo1, first);

TextView twoByOne1 = new TextView(this);
GridLayout.LayoutParams second = new GridLayout.LayoutParams(row2, col0);
second.width = halfScreenWidth;
second.height = quarterScreenWidth;
twoByOne1.setLayoutParams(second);
twoByOne1.setBackgroundColor(Color.BLUE);
twoByOne1.setText("Staff Choices");
twoByOne1.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne1, second);

TextView twoByOne2 = new TextView(this);
GridLayout.LayoutParams third = new GridLayout.LayoutParams(row2, col1);
third.width = halfScreenWidth;
third.height = quarterScreenWidth;
twoByOne2.setLayoutParams(third);
twoByOne2.setBackgroundColor(Color.GREEN);
twoByOne2.setText("Games");
twoByOne2.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne2, third);

TextView twoByOne3 = new TextView(this);
GridLayout.LayoutParams fourth = new GridLayout.LayoutParams(row3, col0);
fourth.width = halfScreenWidth;
fourth.height = quarterScreenWidth;
twoByOne3.setLayoutParams(fourth);
twoByOne3.setBackgroundColor(Color.YELLOW);
twoByOne3.setText("Editor's Choices");
twoByOne3.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
gridLayout.addView(twoByOne3, fourth);

TextView twoByOne4 = new TextView(this);
GridLayout.LayoutParams fifth = new GridLayout.LayoutParams(row3, col1);
fifth.width = halfScreenWidth;
fifth.height = quarterScreenWidth;
twoByOne4.setLayoutParams(fifth);
twoByOne4.setBackgroundColor(Color.MAGENTA);
twoByOne4.setText("Something Else");
twoByOne4.setTextAppearance(this, android.R.style.TextAppearance_Large);
gridLayout.addView(twoByOne4, fifth);

TextView twoByTwo2 = new TextView(this);
GridLayout.LayoutParams sixth = new GridLayout.LayoutParams(row4, colspan2);
sixth.width = screenWidth;
sixth.height = quarterScreenWidth * 2;
twoByTwo2.setLayoutParams(sixth);
twoByTwo2.setGravity(Gravity.CENTER);
twoByTwo2.setBackgroundColor(Color.WHITE);
twoByTwo2.setText("BOTOM");
twoByTwo2.setTextAppearance(this, android.R.style.TextAppearance_Large_Inverse);
gridLayout.addView(twoByTwo2, sixth);

El resultado se verá algo así (en mi Galaxy Nexus):

Diseño en mosaico usando GridLayout

Después de muchos intentos encontré lo que buscaba en este diseño. LinearLayouts incluso espaciados con ImageViews ajustados automáticamente, con una relación de aspecto mantenida. Funciona con paisaje y retrato con cualquier resolución de pantalla e imagen.

Nexus 7Nexus 5Nexus 10



    


        

            

                

                    
                

                

                    
                
            

            

                

                    
                

                

                    
                
            
        
    

Empezando en API 21 la noción de peso se añadió a Diseño de cuadrícula.

Para admitir dispositivos Android más antiguos, puede utilizar el GridLayout de la biblioteca de soporte v7.

compile 'com.android.support:gridlayout-v7:22.2.1'

El siguiente XML da un ejemplo de cómo puede usar pesos para llenar el ancho de la pantalla.




    

    

    

    


Valoraciones y comentarios

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *