J'ai utilisé un tableau statique à disque max hauteurs de la ligne. Ce n'est pas parfait, car le plus tôt colonnes ne sera pas redimensionnée jusqu'à ce que la cellule est réaffiché. Voici le code pour le gonflés de contenu réutilisable vue.
Edit: j'ai eu ce travail correctement, mais j'avais pré-mesurer toutes les cellules avant le rendu. Je l'ai fait en sous-classement GridView et l'ajout d'une mesure de crochet dans le onLayout méthode.
/**
* Custom view group that shares a common max height
* @author Chase Colburn
*/
public class GridViewItemLayout extends LinearLayout {
// Array of max cell heights for each row
private static int[] mMaxRowHeight;
// The number of columns in the grid view
private static int mNumColumns;
// The position of the view cell
private int mPosition;
// Public constructor
public GridViewItemLayout(Context context) {
super(context);
}
// Public constructor
public GridViewItemLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* Set the position of the view cell
* @param position
*/
public void setPosition(int position) {
mPosition = position;
}
/**
* Set the number of columns and item count in order to accurately store the
* max height for each row. This must be called whenever there is a change to the layout
* or content data.
*
* @param numColumns
* @param itemCount
*/
public static void initItemLayout(int numColumns, int itemCount) {
mNumColumns = numColumns;
mMaxRowHeight = new int[itemCount];
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// Do not calculate max height if column count is only one
if(mNumColumns <= 1 || mMaxRowHeight == null) {
return;
}
// Get the current view cell index for the grid row
int rowIndex = mPosition / mNumColumns;
// Get the measured height for this layout
int measuredHeight = getMeasuredHeight();
// If the current height is larger than previous measurements, update the array
if(measuredHeight > mMaxRowHeight[rowIndex]) {
mMaxRowHeight[rowIndex] = measuredHeight;
}
// Update the dimensions of the layout to reflect the max height
setMeasuredDimension(getMeasuredWidth(), mMaxRowHeight[rowIndex]);
}
}
Ici est la fonction de mesure dans mon BaseAdapter sous-classe. Notez que j'ai une méthode updateItemDisplay
qui définit toutes les mesures de texte et d'images sur le point de vue de la cellule.
/**
* Run a pass through each item and force a measure to determine the max height for each row
*/
public void measureItems(int columnWidth) {
// Obtain system inflater
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate temp layout object for measuring
GridViewItemLayout itemView = (GridViewItemLayout)inflater.inflate(R.layout.list_confirm_item, null);
// Create measuring specs
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(columnWidth, MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
// Loop through each data object
for(int index = 0; index < mItems.size(); index++) {
String[] item = mItems.get(index);
// Set position and data
itemView.setPosition(index);
itemView.updateItemDisplay(item, mLanguage);
// Force measuring
itemView.requestLayout();
itemView.measure(widthMeasureSpec, heightMeasureSpec);
}
}
Et enfin, voici le GridView sous-classe mis en place pour mesurer la vue de cellules au cours de la mise en page:
/**
* Custom subclass of grid view to measure all view cells
* in order to determine the max height of the row
*
* @author Chase Colburn
*/
public class AutoMeasureGridView extends GridView {
public AutoMeasureGridView(Context context) {
super(context);
}
public AutoMeasureGridView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AutoMeasureGridView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
if(changed) {
CustomAdapter adapter = (CustomAdapter)getAdapter();
int numColumns = getContext().getResources().getInteger(R.integer.list_num_columns);
GridViewItemLayout.initItemLayout(numColumns, adapter.getCount());
if(numColumns > 1) {
int columnWidth = getMeasuredWidth() / numColumns;
adapter.measureItems(columnWidth);
}
}
super.onLayout(changed, l, t, r, b);
}
}
La raison pour laquelle j'ai le nombre de colonnes que la ressource afin que je puisse avoir un nombre différent basé sur l'orientation, etc.