带有类别的Android GridView?
Posted
技术标签:
【中文标题】带有类别的Android GridView?【英文标题】:Android GridView with categories? 【发布时间】:2011-11-15 21:55:47 【问题描述】:是否可以在 android 中使用带有GridView
的类别或某种标题?
我简要说明了我的想法:
非常感谢。
【问题讨论】:
你最终是如何解决这个问题的? @a.ilic 接受的答案很好。 您好,我设法添加了类别,但它们显示为网格单元格。你能帮我解决这个问题吗? 这只是一个 Gridview 而不是 Listview。 我也遇到了与 Victor 相同的行为。通过在 GridView 而不是 ListView 上简单地使用这个 SeparatedListAdapter,标题也受到网格的约束。 【参考方案1】:您可以直接使用Stickygridheaders 库或作为模型来创建自己的小部件。
【讨论】:
这看起来很甜蜜。感谢您的意见! 刚刚又修改了一遍,这实际上是一个更好的解决方案。 即使看了这两个教程,我也很难做到。你们介意帮助我吗? 你能帮我如何从 ArrarList 传递数据 该项目在github上提到它已被github.com/TonicArtos/SuperSLiM取代【参考方案2】:this code 可能会帮助你。这是 SectionedGridRecyclerViewAdapter,结果如下所示:
【讨论】:
您能建议如何向此适配器添加点击侦听器吗? @AEMLoviji 在 SimpleAdapter 类的 onBindViewHolder 方法上添加:holder.itemView.setOnClickListener 感谢@dilettante 的回答。目前我不再开发移动应用程序了。 3年前我问过这个问题。您提供的方式似乎可以正常工作。【参考方案3】:我认为你可以做到,但你必须实现 Jeff Shrkey 的 SeparatedListAdapter
创建这些分隔列表没有简单的方法,所以我将 SepatedListAdapter 放在一起,它可以快速完成。总而言之,我们正在创建一个新的 BaseAdapter,它可以包含其他几个适配器,每个适配器都有自己的部分标题。
【讨论】:
这怎么有票? SeperatedListAdapter 似乎只适用于 ListViews... @ingsaurabhi 也可以通过这个库github.com/TonicArtos/StickyGridHeaders 为 gridview 工作【参考方案4】:您可以修改通常的列表视图适配器以在每行返回一个网格,请参阅 here
public GenericModelAdapter(Context context, int textViewResourceId, List<Map<String, List<Object>>> items, Map<String, String> sectionHeaderTitles, int numberOfCols, View.OnClickListener mItemClickListener)
super(context, textViewResourceId, items);
this.items = items;
this.numberOfCols = numberOfCols;
layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mItemClickListener = mItemClickListener;
this.sectionHeaderTitles = sectionHeaderTitles;
@Override
public View getView(int position, View convertView, ViewGroup parent)
if(isHeaderPosition(position))
convertView = layoutInflater.inflate(R.layout.grid_header_view, null);
TextView headerText = (TextView)convertView.findViewById(R.id.headerText);
String section = getItemTypeAtPosition(position);
headerText.setText(getHeaderForSection(section));
return convertView;
else
LinearLayout row = (LinearLayout)layoutInflater.inflate(R.layout.row_item, null);
Map<String, List<Object>> map = getItem(position);
List<Object> list = map.get(getItemTypeAtPosition(position));
for (int i = 0; i < numberOfCols; i++)
FrameLayout grid = (FrameLayout)layoutInflater.inflate(R.layout.grid_item, row, false);
ImageView imageView;
if (i < list.size())
GenericModel model = (GenericModel)list.get(i);
if (grid != null)
imageView = (ImageView)grid.findViewWithTag("image");
imageView.setBackgroundResource(model.getImageResource());
TextView textView = (TextView)grid.findViewWithTag("subHeader");
textView.setText(model.getHeader());
grid.setTag(R.id.row, position);
grid.setTag(R.id.col, i);
grid.setOnClickListener(mItemClickListener);
else
if (grid != null)
grid.setVisibility(View.INVISIBLE);
grid.setOnClickListener(null);
row.addView(grid);
return row;
@Override
public int getCount()
int totalItems = 0;
for (Map<String, List<Object>> map : items)
Set<String> set = map.keySet();
for(String key : set)
//calculate the number of rows each set homogeneous grid would occupy
List<Object> l = map.get(key);
int rows = l.size() % numberOfCols == 0 ? l.size() / numberOfCols : (l.size() / numberOfCols) + 1;
// insert the header position
if (rows > 0)
headerPositions.add(String.valueOf(totalItems));
offsetForItemTypeMap.put(key, totalItems);
itemTypePositionsMap.put(key, totalItems + "," + (totalItems + rows) );
totalItems += 1; // header view takes up one position
totalItems+= rows;
return totalItems;
@Override
public Map<String, List<Object>> getItem(int position)
if (!isHeaderPosition(position))
String itemType = getItemTypeAtPosition(position);
List<Object> list = null;
for (Map<String, List<Object>> map : items)
if (map.containsKey(itemType))
list = map.get(itemType);
break;
if (list != null)
int offset = position - getOffsetForItemType(itemType);
//remove header position
offset -= 1;
int low = offset * numberOfCols;
int high = low + numberOfCols < list.size() ? (low + numberOfCols) : list.size();
List<Object> subList = list.subList(low, high);
Map<String, List<Object>> subListMap = new HashMap<String, List<Object>>();
subListMap.put(itemType, subList);
return subListMap;
return null;
public String getItemTypeAtPosition(int position)
String itemType = "Unknown";
Set<String> set = itemTypePositionsMap.keySet();
for(String key : set)
String[] bounds = itemTypePositionsMap.get(key).split(",");
int lowerBound = Integer.valueOf(bounds[0]);
int upperBoundary = Integer.valueOf(bounds[1]);
if (position >= lowerBound && position <= upperBoundary)
itemType = key;
break;
return itemType;
public int getOffsetForItemType(String itemType)
return offsetForItemTypeMap.get(itemType);
public boolean isHeaderPosition(int position)
return headerPositions.contains(String.valueOf(position));
private String getHeaderForSection(String section)
if (sectionHeaderTitles != null)
return sectionHeaderTitles.get(section);
else
return section;
【讨论】:
以上是关于带有类别的Android GridView?的主要内容,如果未能解决你的问题,请参考以下文章
Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现
Android控件GridView之仿支付宝钱包首页带有分割线的GridView九宫格的完美实现
Android - 带有自定义 BaseAdapter 的 Gridview,在位置获得点击视图
Android - 带有自定义 BaseAdapter 的 Gridview,创建 onclicklistener [重复]