Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


Cómo diseñar una 'cuadrícula' de imágenes en el centro de la pantalla

Tengo un conjunto de 12 imágenes para mostrar en un diseño. El número se elige semi arbitrariamente, pero se reduce a 3 horizontal y 4 verticalmente para el modo de retrato y al revés para el paisaje.

La primera implementación fue usar una vista de cuadrícula. El problema es que la altura no puede ser forzada a encajar en la pantalla. Para una solución puedo escalar las imágenes por supuesto, pero es casi imposible calcular la habitación disponible para el gridview: Total screensize se conoce por supuesto, pero usted tiene que "adivinar" el tamaño de la barra de notificación y que doesn ' Parece ser un sollution elegante. El tamaño medido no es realmente de confianza: No estoy haciendo un reinicio completo en el cambio de orientación (para la velocidad), pero la forma en que la pantalla es construir el espacio completo no está disponible en el acto. Al final la conclusión es que no quiero calcular el tamaño de las imágenes y luego escalarlas en consecuencia: creo que es mejor decir cómo las vistas deben encajar en la pantalla, ¿verdad?

Así que el próximo intento es simplemente usar un TableLayout. Usando "ShrinkColumns =" ​​* "las imágenes se ajustaron bien, por lo que el tamaño de las imágenes es ahora como lo queremos.Pero" extra "habitación que podría tener en la altura ahora está dividido entre los tablerows.Esto es de esperar, Pero feo

El código actual parece irrelevante porque no funciona, pero se ve así al final: He eliminado todo el relleno y otras cosas que no parecen relevantes. (Para portait 🙂

<TableLayout android:shrinkColumns="*"> <TableRow> <ImageView/> <ImageView/> <ImageView/> </TableRow> … (repeat 3 tablerows) </TableLayout> 

Para 'escalar' las imágenes demasiado grandes, TableLayout tiene el atributo "shrinkcolumns =" ​​* "".

¿Cómo podemos conseguir que los tres ImageViews se alineen en el centro del TableRow y no se distribuyan uniformemente en el ancho? Y lo mismo ocurre con las columnas verticales, ¿cómo podemos mantener todo junto y no se extienden a lo largo de la altura de la pantalla? Básicamente, el "exceso" de espacio debe ir a los lados como relleno / margen, y ahora va entre las imágenes.

Ejemplo: La pantalla izquierda muestra demasiada distancia izquierda / derecha, la derecha tiene demasiada parte superior / inferior Ejemplo-androblip-layout-image

  • Android Recyclerview GridLayoutManager espaciamiento de columnas
  • Android GridView última columna que se corta
  • Mi vista de cuadrícula muestra sólo una fila
  • Android: ¿Cómo GridView auto_fit encuentra el número de columnas?
  • Cómo forzar a GridView a las celdas de carga
  • Developer.android.com/training proyecto bitmapfun
  • Gridview altura se corta
  • Evitar que la actividad se recargue al acceder al menú de acción contextual haciendo clic en una imagen en la vista de cuadrícula asíncrona
  • One Solution collect form web for “Cómo diseñar una 'cuadrícula' de imágenes en el centro de la pantalla”

    Pensé que esto no debería ser demasiado difícil con una vista personalizada, que debería ser un ejercicio interesante. Esta es mi primera vista personalizada; La regeneración es agradable!

    Limitaciones

    • AspectGrid ignora completamente el tamaño que sus hijos quieren ser. Para sus propósitos, esto parece estar bien. Si se necesita algo más onMeasure , onMeasure necesita mucho trabajo extra.
    • El tamaño que se sugiere por el AspectGrid de AspectGrid se utiliza sin un segundo pensamiento. Esto está relacionado con el número anterior.

    Capturas de pantalla

    Imagen de Paisaje http://i55.tinypic.com/fc8bj4.png

    Captura de pantalla de Portrait http://i55.tinypic.com/zn7qxk.png

    Cómo funciona

    Un parámetro principal es el número de columnas. El número de filas se calcula automáticamente, porque sabemos el número de hijos. Otro parámetro principal es la relación de aspecto que queremos utilizar para los niños (establecida en 1 para los cuadrados).

    En onLayout , recibimos el tamaño final de la cuadrícula, por lo que podemos calcular el ancho máximo y la altura de los niños.

    A continuación, comprobar esto en contra de la relación de aspecto. Si los niños son demasiado altos, los hacemos más cortos (como en el ejemplo de retrato). Si son demasiado anchos, los hacemos más estrechos (como en el ejemplo del paisaje).

    Eso es todo al respecto; El resto es sólo fontanería.

    El código

    com/photogrid/AspectGrid.java : La clase ViewGroup real

     package com.photogrid; import android.content.Context; public class AspectGrid extends ViewGroup { private int mNumColumns = 1; private int mHorizontalSpacing = 0; private int mVerticalSpacing = 0; private float mChildAspectRatio = 1.0f; public AspectGrid(Context context) { super(context); } public AspectGrid(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AspectGrid(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); try { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AspectGrid); setNumColumns(a.getInt(R.styleable.AspectGrid_numColumns, mNumColumns)); setHorizontalSpacing(a.getDimensionPixelSize(R.styleable.AspectGrid_horizontalSpacing, mHorizontalSpacing)); setVerticalSpacing(a.getDimensionPixelSize(R.styleable.AspectGrid_verticalSpacing, mVerticalSpacing)); setChildAspectRatio(a.getFloat(R.styleable.AspectGrid_childAspectRatio, mChildAspectRatio)); a.recycle(); } catch (RuntimeException ex) { throw ex; } } public int getNumColumns() { return mNumColumns; } public void setNumColumns(int numColumns) { if (numColumns < 1) throw new IllegalArgumentException("numColumns must be at least 1"); if (numColumns != mNumColumns) { mNumColumns = numColumns; requestLayout(); } } public int getHorizontalSpacing() { return mHorizontalSpacing; } public void setHorizontalSpacing(int horizontalSpacing) { mHorizontalSpacing = horizontalSpacing; } public int getVerticalSpacing() { return mVerticalSpacing; } public void setVerticalSpacing(int verticalSpacing) { mVerticalSpacing = verticalSpacing; } public float getChildAspectRatio() { return mChildAspectRatio; } public void setChildAspectRatio(float childAspectRatio) { if (childAspectRatio <= 0) throw new IllegalArgumentException("childAspectRatio must be positive"); if (childAspectRatio != mChildAspectRatio) { mChildAspectRatio = childAspectRatio; requestLayout(); } } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int widthSize = MeasureSpec.getSize(widthMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); int measuredWidth = widthSize; int measuredHeight = heightSize; int width = Math.max(measuredWidth, getSuggestedMinimumWidth()); int height = Math.max(measuredHeight, getSuggestedMinimumHeight()); setMeasuredDimension(width, height); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { int childCount = getChildCount(); if (childCount <= 0) return; int innerWidth = r - l - getPaddingLeft() - getPaddingRight(); int innerHeight = b - t - getPaddingBottom() - getPaddingTop(); int numRows = (childCount + mNumColumns - 1) / mNumColumns; int leftEdge = getPaddingLeft(); int topEdge = getPaddingTop(); int horizontalStride = (innerWidth + mHorizontalSpacing) / mNumColumns; int verticalStride = (innerHeight + mVerticalSpacing) / numRows; int childWidth = horizontalStride - mHorizontalSpacing; int childHeight = verticalStride - mVerticalSpacing; if (childHeight * mChildAspectRatio > childWidth) { childHeight = (int)(childWidth / mChildAspectRatio); verticalStride = childHeight + mVerticalSpacing; topEdge = (innerHeight + mVerticalSpacing - numRows * verticalStride) / 2; } else { childWidth = (int)(childHeight * mChildAspectRatio); horizontalStride = childHeight + mHorizontalSpacing; leftEdge = (innerWidth + mHorizontalSpacing - mNumColumns * horizontalStride) / 2; } for (int i = 0; i < childCount; ++i) { View child = getChildAt(i); int row = i / mNumColumns; int column = i % mNumColumns; int left = leftEdge + column * horizontalStride; int top = topEdge + row * verticalStride; child.layout( left, top, left + childWidth, top + childHeight); } } } 

    res/values/attrs.xml : Declaración de atributos para su uso en XML

     <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="AspectGrid"> <attr name="numColumns" format="integer"/> <attr name="horizontalSpacing" format="dimension"/> <attr name="verticalSpacing" format="dimension"/> <attr name="childAspectRatio" format="float"/> </declare-styleable> </resources> 

    res/layout/main.xml : El ejemplo utilizado en las capturas de pantalla anteriores

     <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res/com.photogrid" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <com.photogrid.AspectGrid android:layout_width="fill_parent" android:layout_height="fill_parent" android:padding="5dp" app:numColumns="3" app:horizontalSpacing="5dp" app:verticalSpacing="5dp" app:childAspectRatio="1.0" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffcccc" android:text="Item 1" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ccffcc" android:text="Item 2" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ccccff" android:text="Item 3" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffffcc" android:text="Item 4" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ffccff" android:text="Item 5" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#ccffff" android:text="Item 6" /> </com.photogrid.AspectGrid> </LinearLayout> 
    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.