@Override public View getView(final int position, final View convertView, final ViewGroup parent) { LinearLayout layout = findOrInitializeLayout(convertView); final RowInfo<T> rowInfo = itemsPerRow.get(position); final List<T> rowItems = new ArrayList<>(); rowItems.addAll(rowInfo.getItems()); // Index to control the current position // of the current column in this row int columnIndex = 0; // Index to control the current position // in the array of all the items available for this row int currentIndex = 0; int spaceLeftInColumn = rowInfo.getRowHeight(); while (!rowItems.isEmpty() && columnIndex < listView.getNumColumns()) { final T currentItem = rowItems.get(currentIndex); if (spaceLeftInColumn == 0) { // No more space in this column. Move to next one columnIndex++; currentIndex = 0; spaceLeftInColumn = rowInfo.getRowHeight(); continue; } // Is there enough space in this column to accommodate currentItem? if (spaceLeftInColumn >= currentItem.getRowSpan()) { rowItems.remove(currentItem); int index = items.indexOf(currentItem); final LinearLayout childLayout = findOrInitializeChildLayout(layout, columnIndex); final View childConvertView = viewPool.get(); final View v = getActualView(index, childConvertView, parent); v.setTag(currentItem); v.setOnClickListener(this); v.setOnLongClickListener(this); spaceLeftInColumn -= currentItem.getRowSpan(); currentIndex = 0; v.setLayoutParams( new LinearLayout.LayoutParams(getRowWidth(currentItem), getRowHeight(currentItem))); childLayout.addView(v); } else if (currentIndex < rowItems.size() - 1) { // Try again with next item currentIndex++; } else { break; } } if (listView.isDebugging() && position % 20 == 0) { Log.d(TAG, linearLayoutPool.getStats("LinearLayout")); Log.d(TAG, viewPool.getStats("Views")); } return layout; }