66 votes

Android: Comment GridView auto_fit trouve-t-il le nombre de colonnes?

J'aimerais mieux comprendre comment Gridview d'œuvres, notamment auto_fit. Voici le XML mise en page:

<?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"
/>

Et il fonctionne très bien avec une série de six vignettes (48*48 pixels). En mode portrait, il affiche une rangée de six colonnes.

with

Ce que je ne comprends pas, c'est pourquoi la ligne android:columnWidth="60dp" est nécessaire, parce que auto_fit s'attend à trouver le bon nombre de colonnes.
Sans la ligne android:columnWidth="60dp", il affiche une grille de 3 lignes et 2 colonnes.

without

Voici l' ImageAdapter classe:

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
    };
}

Je vous remercie pour votre aide.

96voto

Vaiden Points 2186

En regardant le contrôle GridView source, il est clair que la définition du rembourrage et de la hauteur de votre ImageView ne sera pas vous aider du tout. Lorsque la largeur d'une colonne n'est pas spécifié, il a juste choisit un nombre prédéfini de colonnes (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 solution est de mesurer votre taille de la colonne avant de la GridView la largeur de la colonne. Voici un moyen rapide pour mesurer les points de Vue à l'écran:

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;
}

Et puis il suffit de régler le GridView la largeur de la colonne:

gridView.setColumnWidth( width );

7voto

Sherif elKhatib Points 23987

Selon le android:numColumns documentation

auto_fit Afficher autant de colonnes que possible pour remplir l'espace disponible.

Donc, si vous insérez ImageViews avec

padding ensemble de zero

margin ensemble de zero

layout_width ensemble de wrap_content

layout_height ensemble de wrap_content

Le contrôle gridView doit contenir le plus grand nombre possible d'enfants


Gardez à l'esprit Votre ImageViews sont peut-être arriver à une certaine échelle (:

1voto

Stephan Wiesner Points 11

Je trouve que je sais généralement quelle est la largeur de mes colonnes. Soit je connais la taille de mes images, soit je laisse l’utilisateur déterminer cette taille. Par conséquent, je peux simplement définir la largeur de mon activité:

     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); 
 

C'est tout . . .

Salutations de Lucerne, Stephan

1voto

user2347763 Points 46

"wrap_content" fonctionne comme le mot wrap pour les éditeurs de texte: si l'image ne peut pas tenir dans la dernière taille de colonne, elle passe à la ligne suivante. Toutefois, si vous définissez l'attribut numcolumns sur un nombre, la grille peut étirer / ajuster les colonnes (stretchModde est une autre propriété que vous pouvez utiliser conjointement).

ps - bien que vous ayez coché la réponse, vous seriez heureux de savoir si cela vous a aidé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X