关于Android的GridView添加HeaderView,FooterView.

最近有一个需求,需要在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;
    }

最近闲暇写了一篇文章,实现了上述功能,感兴趣的可以点击下面的链接

点我下载代码



你可能感兴趣的:(关于Android的GridView添加HeaderView,FooterView.)