web-dev-qa-db-fra.com

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

J'aimerais mieux comprendre comment fonctionne Gridview, en particulier auto_fit. Voici la mise en page XML:

<?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 cela fonctionne bien avec une série de six vignettes (48 * 48 pixels). En mode portrait, il affiche une ligne, six colonnes.

with

Ce que je ne comprends pas, c'est pourquoi la ligne Android:columnWidth="60dp" est nécessaire, car auto_fit doit trouver le nombre correct de colonnes.
Sans la ligne Android:columnWidth="60dp", il affiche une grille de 3 lignes et 2 colonnes.

without

Voici la classe 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
    };
}

Merci de votre aide.

65
galath

En regardant la source GridView, il est clair que le réglage du remplissage et de la hauteur de votre ImageView ne vous aidera pas du tout. Lorsqu'une largeur de colonne n'est pas spécifiée, il choisit simplement 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 consiste à mesurer votre taille de colonne avant de définir la largeur de colonne de GridView. Voici un moyen rapide de mesurer les vues hors é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 vous venez de définir la largeur de colonne de GridView:

gridView.setColumnWidth( width );
94
Vaiden

Selon le Android: documentation de numColumns

auto_fit Affichez autant de colonnes que possible pour remplir l’espace disponible.

Donc, si vous insérez ImageViews avec

padding mis à zero

margin mis à zero

layout_width mis à wrap_content

layout_height mis à wrap_content

GridView doit contenir le nombre maximal d'enfants possible


Gardez à l'esprit Vos images sont peut-être mises à l'échelle (:

7
Sherif elKhatib

Cela peut aider quelqu'un ... Vous devez trouver la largeur de la taille manuellement. En fonction de la largeur, vous pouvez définir la colonne

        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);
3
Aristo Michael

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 dans 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

1
Stephan Wiesner

"wrap_content" fonctionne comme Word Wrap pour les éditeurs de texte: si l'image ne rentre pas 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é.

1
user2347763