像此先前的人一樣,我在GridView項之間有不必要的重叠:
請註意除最右邊的每一列中的文字。
与先前的問题不同的是,我 don't want a constant row height .我希望行高根据 accommodate the tallest content 在每一行中,以有效利用螢幕空間。
所以,在我走破旧的"克隆並拥有"之路之前,
is there a trick I'm missing here?
我可以使用TableLayout,但這需要我實現
numColumns="auto_fit"
我自己(因為我只想在手機螢幕上顯示一长列),而且它也不是AdapterView,感覺像應该這樣。
Edit: 實際上,在這裏克隆和拥有並不實際. GridView依赖於其父級和同級類的不可訪問的部分,並且会匯致至少匯入6000行代碼(AbsListView,AdapterView等)。
- 5月前1 #
- 5月前2 #
基於Chris的資訊,我使用了此變通方法 確定其他GridView項的高度時,本機GridView使用的引用视圖的大小。
我建立了這个GridViewItemContainer自定義類:
/** * This class makes sure that all items in a GridView row are of the same height. * (Could extend FrameLayout, LinearLayout etc as well, RelativeLayout was just my choice here) * @author Anton Spaans * */ public class GridViewItemContainer extends RelativeLayout { private View[] viewsInRow; public GridViewItemContainer(Context context) { super(context); } public GridViewItemContainer(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public GridViewItemContainer(Context context, AttributeSet attrs) { super(context, attrs); } public void setViewsInRow(View[] viewsInRow) { if (viewsInRow != null) { if (this.viewsInRow == null) { this.viewsInRow = Arrays.copyOf(viewsInRow, viewsInRow.length); } else { System.arraycopy(viewsInRow, 0, this.viewsInRow, 0, viewsInRow.length); } } else if (this.viewsInRow != null){ Arrays.fill(this.viewsInRow, null); } } @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (viewsInRow == null) { return; } int measuredHeight = getMeasuredHeight(); int maxHeight = measuredHeight; for (View siblingInRow : viewsInRow) { if (siblingInRow != null) { maxHeight = Math.max(maxHeight, siblingInRow.getMeasuredHeight()); } } if (maxHeight == measuredHeight) { return; } int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); switch(heightMode) { case MeasureSpec.AT_MOST: heightMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(maxHeight, heightSize), MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); break; case MeasureSpec.EXACTLY: // No debate here. Final measuring already took place. That's it. break; case MeasureSpec.UNSPECIFIED: heightMeasureSpec = MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.EXACTLY); super.onMeasure(widthMeasureSpec, heightMeasureSpec); break; } }
在適配器的getView方法中,將convertView作為子級包裝在新的GridViewItemContainer中,或使其成為專案佈局的頂部XML元素:
// convertView has been just been inflated or came from getView parameter. if (!(convertView instanceof GridViewItemContainer)) { ViewGroup container = new GridViewItemContainer(inflater.getContext()); // If you have tags, move them to the new top element. E.g.: container.setTag(convertView.getTag()); convertView.setTag(null); container.addView(convertView); convertView = container; } ... ... viewsInRow[position % numColumns] = convertView; GridViewItemContainer referenceView = (GridViewItemContainer)convertView; if ((position % numColumns == (numColumns-1)) || (position == getCount()-1)) { referenceView.setViewsInRow(viewsInRow); } else { referenceView.setViewsInRow(null); }
其中numColumns是GridView中的列數," viewsInRow"是"位置"所在当前行的View列表。
- 5月前3 #
我做了很多研究,但發現不完整 答案或很难理解解決方案的內容,但最终找到了一个正確解釋的答案。
我的問题是正確地將gridview專案調整為高度.這个
Grid-view
当您所有视圖的高度相同時,效果很好.但是,当您的视圖具有不同的高度時,網格將無法達到預期的效果.视圖將彼此重叠,从而匯致an-aesthetically
令人愉悦的網格。在此解決方案中,我在XML佈局中使用了此類。
我使用了此解決方案,並且效果很好,非常感谢。--Abhishek Mittal
- 5月前4 #
如果將GridView或ListView轉換為RecyclerView,則不会發生此問题.而且,您無需建立自定義的GridView類。
- 5月前5 #
為GridView賦予權重也可以作為子元素在LinearLayouts內的GridView上使用.這樣,GridView会將子項填充到视口中,因此只要它们適合螢幕,您就可以查看它的項(然後滚動)。
但始终避免在ScrollViews中使用GridViews.否則,您將需要計算每个child的身高,並將其重新分配為上面的蔡斯答案。
<GridView android:id="@+id/gvFriends" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:verticalSpacing="5dp" android:horizontalSpacing="5dp" android:clipChildren="false" android:listSelector="@android:color/transparent" android:scrollbarAlwaysDrawHorizontalTrack="false" android:scrollbarAlwaysDrawVerticalTrack="false" android:stretchMode="columnWidth" android:scrollbars="none" android:numColumns="4"/>
我使用靜態陣列来驅動最大高度 行.這是不完美的,因為在重新顯示该單元格之前,不会調整前几列的大小.這是膨脹的可重用內容视圖的代碼。
Edit :我正確地完成了這項工作,但是在渲染之前我已经預先測量了所有單元格.我是通過子類化GridView並在onLayout方法中添加一个測量钩子来實現的。
這是我的BaseAdapter子類中的測量功能.請註意,我有一个方法
updateItemDisplay
在视圖單元格上設置所有適当的文字和圖像。最後,這是GridView子類,用於在佈局期間測量视圖單元:
我將列數作為資源的原因是,以便可以根据方向等获得不同的列數。