2011-08-02 21 views
60

Me gustaría entender mejor cómo funciona Gridview, en particular auto_fit. Este es el diagrama XML:Android: ¿Cómo encuentra GridView auto_fit la cantidad de columnas?

<?xml version="1.0" encoding="utf-8"?> 
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gridview" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:columnWidth="60dp" 
    android:numColumns="auto_fit" 
/> 

y funciona bien con una serie de seis miniaturas (48 * 48 píxeles). En modo retrato, muestra una fila, seis columnas.

with

Lo que no entiendo es por qué la línea android:columnWidth="60dp" es necesario, ya que se espera auto_fit para encontrar el número correcto de columnas.
Sin la línea android:columnWidth="60dp", muestra una cuadrícula de 3 filas y 2 columnas.

without

Aquí es la clase ImageAdapter:

package com.examples.HelloGridView; 

import android.content.Context; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.BaseAdapter; 
import android.widget.ImageView; 

public class ImageAdapter extends BaseAdapter { 
    private Context mContext; 

    public ImageAdapter(Context c) { 
     mContext = c; 
    } 

    public int getCount() { 
     return mThumbIds.length; 
    } 

    public Object getItem(int position) { 
     return null; 
    } 

    public long getItemId(int position) { 
     return 0; 
    } 

    // create a new ImageView for each item referenced by the Adapter 
    public View getView(int position, View convertView, ViewGroup parent) { 
     ImageView imageView; 
     if (convertView == null) { // if it's not recycled, initialize some attributes 
      imageView = new ImageView(mContext); 
      imageView.setPadding(0, 0, 0, 0); 
     } else { 
      imageView = (ImageView) convertView; 
     } 

     imageView.setImageResource(mThumbIds[position]); 
     return imageView; 
    } 

    // references to our images 
    private Integer[] mThumbIds = { 
      R.drawable.ic_1, R.drawable.ic_2, 
      R.drawable.ic_3, R.drawable.ic_4, 
      R.drawable.ic_5, R.drawable.ic_6 
    }; 
} 

Gracias por su ayuda.

Respuesta

90

En cuanto a la fuente de GridView, es evidente que al establecer la el relleno y la altura en su ImageView no lo ayudarán en absoluto. Cuando no se especifica un ancho de columna, sólo se elige un número preestablecido de columnas (2):

private void determineColumns(int availableSpace) { 

    ... 

    if (mRequestedNumColumns == AUTO_FIT) { 
     if (requestedColumnWidth > 0) { 
      // Client told us to pick the number of columns 
      mNumColumns = (availableSpace + requestedHorizontalSpacing)/
        (requestedColumnWidth + requestedHorizontalSpacing); 
     } else { 
      // Just make up a number if we don't have enough info 
      mNumColumns = 2; 
     } 
    } else { 
     // We picked the columns 
     mNumColumns = mRequestedNumColumns; 
    } 

    if (mNumColumns <= 0) { 
     mNumColumns = 1; 
    } 

    ... 

La solución es medir el tamaño de la columna antes de establecer el ancho de columna de GridView. Esta es una manera sencilla de medir Vistas fuera de la pantalla:

public int measureCellWidth(Context context, View cell) 
{ 

    // We need a fake parent 
    FrameLayout buffer = new FrameLayout(context); 
    android.widget.AbsListView.LayoutParams layoutParams = new android.widget.AbsListView.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 
    buffer.addView(cell, layoutParams); 

    cell.forceLayout(); 
    cell.measure(1000, 1000); 

    int width = cell.getMeasuredWidth(); 

    buffer.removeAllViews(); 

    return width; 
} 

Y a continuación, que acaba de establecer el ancho de columna de GridView:

gridView.setColumnWidth(width); 
+5

¿Dónde debo escribir el código anterior? – Nishant

+0

Es un ejemplo conceptual de cómo resolver el problema. Como necesita saber el ancho real, he incluido un código snipet que lo mide. – Vaiden

+0

@Nishant Puede usar setColumnWidth() justo después de usar setAdapter() en su GridView. –

6

Según la Pantalla android:numColumns documentation

auto_fit tantas columnas como sea posible para llenar el espacio disponible.

Así que si inserta ImageView s con

padding conjunto de zero

margin conjunto de zero

layout_width conjunto de wrap_content

layout_height conjunto de wrap_content

GridView debe contener el número máximo posible de los niños


Tenga en cuenta Sus ImageViews tal vez se están escalados (:

+0

He agregado el código ImageView. El margen no está establecido, veré si es lo que extrañé. Gracias. – galath

+3

Sí, no necesariamente creo en la documentación de Android. ¡Algunos lugares aún tienen código de ejemplo que usa funciones anteriores a la 1.0! – Timmmm

+1

Timmmm lo consigue, la respuesta aceptada muestra que establecer dimensiones y opciones de diseño en ImageView no hace nada en este caso; el componente Gridview no es particularmente completo con sus cálculos. Por lo general, es el valor predeterminado de 2. –

2

Me parece que por lo general se como amplia Quiero que mis columnas que sean.O sé el tamaño de mis imágenes o dejo que el usuario determine ese tamaño. Por lo tanto, puedo establecer el ancho en mi Actividad:

gridview = (GridView) findViewById(R.id.gridview); 
    SharedPreferences mySettings; 
    mySettings = getSharedPreferences(Constants.PREFERENCES, Context.MODE_PRIVATE); 
    int gridSize = 50 * Integer.parseInt(mySettings.getString("gridSize", "3")); 
    gridview.setColumnWidth(gridSize + 10); 

Eso es todo. . .

Saludos desde Lucerna, Stephan

1

"wrap_content" funciona como lo hace el ajuste de línea para editores de texto - si la imagen no puede encajar en el último tamaño de la columna, la imagen fluye a la siguiente fila. Sin embargo, si configura el atributo numcolumns en un número, entonces la cuadrícula puede estirar/ajustar las columnas (stretchModde es otra propiedad que puede usar en conjunto).

ps - aunque ha marcado la respuesta, estaría encantado de saber si esto ayudó.

4

Esto puede ayudar a alguien ... Necesita encontrar el tamaño de ancho manualmente. Según el tamaño del ancho, puede establecer la columna

 float scalefactor = getResources().getDisplayMetrics().density * 100; 
     int number = getWindowManager() 
       .getDefaultDisplay().getWidth(); 
     int columns = (int) ((float) number/scalefactor)/2; 
     if (columns == 0 || columns == 1) 
      columns = 2; 
     gridView.setNumColumns(columns); 
+0

¿Qué es 100 ...? –

Cuestiones relacionadas