最近有一个需求,需要在GridView之上添加HeaderView和FooterView,并实现延迟加载(LazyLoad),但是经过我3天的研究和尝试,只能说自己真的太弱了,真的没有解决方法。
所以,这里我奉劝大家,放弃这个方案吧。
强烈建议大家使用ListView来实现GridView的效果。
以下说说我走过的几条错误的路:
1FooterView添加比较简单,而且可以实现,因为GridView可以位于一个ViewGroup中,通过Visable的控制,可以轻易达到这个效果,这个我就不再多说,主要来说说HeaderView。
1.第一次痛苦的尝试:
Override的GridView,设置Padding,通过控制OnTouchEvent的事件,改变padding并且移动HeaderView。这个方法初看来是十分不错的,可是问题也随之而来。如果HeaderView非常高,GridView就会非常小,手势在ViewGroup中就被拦截到了。而不会反应给GridView,当然,你可以重写ViewGroup,但这其中的麻烦不言而喻,所以我果断放弃了。
2.第二次痛苦的尝试:
想法和添加FooterView一样,通过控制View的Visable来达到目的,可是却发现HeaderView是不随GridView滚动的,这个问题本来下手之前就应该遇见到,结果...所以真的应该三思而后行。
3.第三次痛苦的尝试:
通过Override的ViewGroup,然后自己排列,这个我觉得十分麻烦,因为HeaderView并没有真正的属于GridView,所以一切控制起来非常不方便!!!中途就放弃了。
4.第四次痛苦的尝试:
通过对GridView设置一个OnScrollListener,通过callback来改变自身的padding,然后在padding的地方添加一个View,发现还是不行!!!
5.第五次痛苦的尝试:
dVie通过LinearLayout嵌套GridView,之后再加入ScrollView来控制滚动,结果发现ScrollView是无缓存的,和LazyLoad是冲突的,而且对大量数据根本没法处理,果断放弃!
不过今天终于解决这个问题了,改ListView成GridView还是非常简单的。思路是这样的,一个LinearLayout 根据
mColumns 的具体数值去装入child(就是之前的getView),这样就可以轻松实现gridView的功能了,所以只需要修改getView和getCount就可以了,代码看图片,不懂的QQ咨询或者留言吧!这里就不多说了
QQ 157688302
@Override public View getView(int position, View convertView, ViewGroup parent) { System.out.println("position: " + position); return getGridView(position, convertView, parent); } public View getGridView(int position,View convertView,ViewGroup parent){ if(position == getCount() - 1){ mFm.doLazyLoad(); } if(mColumns == 1){ View child = super.getView(position, convertView, parent); setOnItemClickListenerIfNeed(child, position, position); return child; }else{ ViewGroup root = null; if(convertView != null && convertView instanceof ViewGroup){ root = (ViewGroup) convertView; }else{ root = createRoot(); root.setClickable(false); root.setFocusable(false); } //columns = 3 //pos --> real pos //0 --> 0 1 2 //1 --> 3 4 5 //2 --> 6 7 8 //so do this return bindView(root, position); } }
private View bindView(ViewGroup root, int position) { final int childCount = root.getChildCount(); for (int i = 0; i < mColumns; i++) { // real position int index = mColumns * position + i; // 不足一行时,直接返回现有状态 if (index == super.getCount()) { // fix bug : root是有可能是系统缓存的root,这里直接返回root将导致Bug。
//如果此行数量不够columns,就会使用缓存的root里的child,为了避免这个问题,必须 // 将缓存的child移除。 // by Chaos at 2012-12-17 removeCacheChild(root, index); break; } View child = super.getView(index, root.getChildAt(i), root); setOnItemClickListenerIfNeed(child, position, index); if (childCount == mColumns) { // root已经包含了Item,就没有必要继续添加了。 continue; } else { if (i == 0 && childCount != 0) { // 如果root已经包含item,但是并不全,这里就移除重新添加 // FIXME 也许还有更好的方案 root.removeAllViews(); } LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams( // LinearLayout.LayoutParams.WRAP_CONTENT, mFm.getWidth() / mColumns, LinearLayout.LayoutParams.WRAP_CONTENT); child.setFocusable(true); child.setClickable(true); if (child instanceof ViewGroup) { ((ViewGroup) child) .setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); } root.addView(child, lp); } } return root; }
@Override public int getCount() { int count = (int) Math.ceil(super.getCount() / (double)mColumns); return count; }
最近闲暇写了一篇文章,实现了上述功能,感兴趣的可以点击下面的链接
点我下载代码