Android的GridView不能添加HeaderView,谷歌在Galley中已经实现了为GridView添加HeaderView的实现,源码:https://android.googlesource.com/platform/packages/apps/Gallery2/+/idea133/src/com/android/photos/views/HeaderGridView.java
该方案能较完美的解决为GridView添加HeaderView,适用大部分情况,但有种特殊需求不能满足:
问题一:HeaderView需要左,右都顶到父布局,列表项需要有左右边距和horizontalSpacing,这时候如果对HeaderGridView设置paddingLeft和paddingRight会发现HeaderView也有左右边距,未能左右顶到父布局,如果不设置paddingLeft和paddingRight,列表项又有左右边距,很难完美解决HeaderView和itemView对Padding的不同需求。
原因分析:该HeaderGridView是通过新建一个Adapter封装原来的Adapter,在新的Adapter中的getView根据需要,有一个headerView就将headerView添加到一个宽度和gridview同宽的ViewGroup中,然后返回这个ViewGroup作为该行的第一个item项,然后同行的后面位置用空view返回(其实ListView添加HeaderView和footerView也是封装Adapter的方式实现的),也就是说HeaderView还是GridView的item,会受到GridView的padding属性的影响,所以会出现该问题。
解决方案:HeaderGridView不设置padding和horizontalSpacing,满足HeaderView的需求,这是GridView会把item进行等分,在Adapter的初始化中计算每个item的宽度和边距,然后在getView中对item的位置进行判断来设置item的边距和宽度,代码如下:
public MyAdapter extends BaseAdapter {
ViewGroup.LayoutParams ItemLp;// 局部复用的item布局参数
int padding;// 用以重新计算每个Item项内部的padding全局padding
int columns;// GridView的列数
public MyAdapter() {
原初始化逻辑
initItemWidth();
}
private void initItemWidth() {
int parentWidht = mGridView.getMeasureWidth();
columns = mGridView.getNumColumns();
padding = mContext.getResources().getDimensionPixelOffset(R.dimen.grid_item_padding);// dimen.xml文件中设置的girdview的左右边距和gridview的水平间距
int itemWidth = (parentWidht - padding * (colums + 1)) / colums;// 总宽度减去columns + 1份padding进行columns等分
ItemLp = new ViewGroup.LayoutParams(itemWidth, ViewGroup.LayoutParams.MATCH_PARENT);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
...原getView处理逻辑
int index = positon % colums;// 计算item在每行的位置
for (int i = 0; i < colums; i ++) {
if (i = index) {
// 通过观察示意图可以得出item的paddingLeft值得表达式,推导过程:
// 每个item左右padding的总和:itemPading = parentView / columns - itemWidth;
// 第i个item的paddingRight加下一item的paddingLeft的和为padding;
// 第一个item的paddingLeft = padding;
// 根据这些条件推导出第i个item的paddingLeft公式为:padding * (columns - i) / columns
convertView.setPadding(padding * (columns - i) / columns, 0 , 0, 0);
}
}
viewHolder.layout_item.setLayoutParams(ItemLp);// viewHolder.layout_item为item布局的中添加的第二层布局
return convertView;
}
原Adapter其他处理逻辑
}