26

A quick question:

In ListView I use this code:

list.addHeaderView(headerView);

How to deal with it when working on gridview?

Thanks.

mmBs
  • 8,421
  • 6
  • 38
  • 46
necixy
  • 4,964
  • 5
  • 38
  • 54

11 Answers11

32

There is no support for header or footer views with GridView, sorry.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • 14
    Any other trick that could work? I want to show few details on top of gridview and I want that information to be scrollable along with gridview. Any help would be appreciated. :) – necixy Apr 26 '11 at 13:39
  • @Guru: Sorry, I am not aware of anything that will readily work for that. You cannot put a `GridView` in a `ScrollView`, for example. – CommonsWare Apr 26 '11 at 14:25
25

There is a quite good implementation of GridView with header support in Google Photos application, as it's OSS code you can use it as is or take it as a reference for your own implementation: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.3_r2.1/com/android/photos/views/HeaderGridView.java

Basic idea is quite simple - WrapperAdapter creates an fake row by increasing number of items by number of columns and then return a header view for the item.

AlexM
  • 636
  • 8
  • 7
  • Works very well, thanks! Just have to be aware that it adds an additional item to your array adapter. – Emanuel Canha Jan 17 '14 at 11:58
  • Thanks! There is an issue with fast scroll, but I simply fixed it after minor changes: HeaderViewGridAdapter extends BaseAdapter in HeaderGridView.java. – FeelGood Apr 25 '14 at 17:15
  • 8
    Why does Google insist on having components that should be core hidden in their own applications? – MLProgrammer-CiM May 06 '14 at 13:14
  • 2
    I agree, Google makes it bloody difficult to add style. It should be basic functionality to have a header and footer in a gridview ! – Someone Somewhere Jun 03 '14 at 19:07
  • This worked like a charm and should be the accepted answer! Remember to make HeaderGridViewAdapter extend BaseAdapter if you're using fast scroll, just like @FeelGood said. – kgrevehagen Aug 17 '14 at 14:38
  • has anyone tweaked it for footer instead of header? – Gintas_ Aug 23 '14 at 19:10
  • For views that need footer I used http://tonicartos.github.io/StickyGridHeaders/ . – AlexM Aug 25 '14 at 23:12
  • @FeelGood Can you explain a bit more. i have same issue, i changed my adapter to extend BaseAdapter instead of listAdapter and still having issue – Muhammad Umar Jan 26 '15 at 14:12
  • @muhammad-umar If you try to use fast scroll in suggested HeaderGridView.java you will get ClassCastException. To fix it just change HeaderGridView.java in line 214 to 'private static class HeaderViewGridAdapter extends BaseAdapter ...' – FeelGood Jan 26 '15 at 14:29
  • HeaderGridView has couple of bugs! – Muhammad Babar Dec 03 '15 at 06:02
5

You can use this. The footer appears/hides at the bottom of the grid when you reach/leave the last number of items. It does not actually scroll, but I hardly notice the difference.

In your activity/fragment's onCreate/onCreateView you add an OnScrollListener to the GridView:

    ....
    GridView gridview = (YMAnimatedGridview) v.findViewById(R.id.my_gridview);
    gridview.setAdapter(adapter);
    final View footerView = mainView
            .findViewById(R.id.my_grid_footer_view);
    gridview.setOnScrollListener(new GridView.OnScrollListener() {

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,
                int visibleItemCount, int totalItemCount) {

                if (firstVisibleItem + visibleItemCount == totalItemCount) {

                    // last item in grid is on the screen, show footer:
                    footerView.setVisibility(View.VISIBLE);

                } else if (footerView.getVisibility() != View.GONE) {

                    // last item in grid not on the screen, hide footer:
                    footerView.setVisibility(View.GONE);
                }
            }

        @Override
        public void onScrollStateChanged(AbsListView view,
                int scrollState) {
        }
    });

Your layout should look something like the below. Notice the layout_weight (and layout_height) parameter in the gridview, it is needed to make the correct space for the footer when it becomes visible.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <GridView
        android:id="@+id/my_gridview"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:columnWidth="160dp"
        android:gravity="center_horizontal"
        android:horizontalSpacing="12dp"
        android:numColumns="auto_fit"
        android:layout_weight="1"
        android:stretchMode="columnWidth"
        android:verticalSpacing="6dp" />

    <TextView
        android:id="@+id/my_grid_footer_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:layout_marginBottom="8dp"
        android:orientation="horizontal"
        android:visibility="gone"
        android:text="footer text here" >
    </TextView>
</LinearLayout>
Frank
  • 12,010
  • 8
  • 61
  • 78
5

enter image description here

Sample code:

GridViewWithHeaderAndFooter gridView = (GridViewWithHeaderAndFooter) v.findViewById(R.id.ly_image_list_grid);

LayoutInflater layoutInflater = LayoutInflater.from(this);
View headerView = layoutInflater.inflate(R.layout.test_header_view, null);
View footerView = layoutInflater.inflate(R.layout.test_footer_view, null);
gridView.addHeaderView(headerView);
gridView.addFooterView(footerView);

Gradle build: .

compile 'in.srain.cube:grid-view-with-header-footer:1.0.12'
Ajay Venugopal
  • 1,544
  • 1
  • 17
  • 30
4

You'd have to use a ListView, then make each row of the list look like it's actually a row of a grid. So if you have a 3 column grid, you'd make a layout for the ListView that looks like 3 columns. You'd then have to modify certain aspects of the Adapter to make it work so that each ListView row actually represents 3 lines of data -- so you know, getCount()/3 type stuff.

Tyler
  • 84
  • 4
  • You can get some of this work done for you by using HeaderViewListAdapter to wrap your existing adaptor. If you look at [the source](http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/1.5_r4/android/widget/HeaderViewListAdapter.java) it's quite obvious how to use it. – MarkDaniel Nov 19 '12 at 11:43
4

How about checking for the "0" index element in your adapter? You can inflate the custom view for the first one.

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View view = convertView;
            if(view==null){
                 if(position==0){
                      //  ...inflate header view
                 }else{
                      //  ...do as usual

Haven't tested it, but should work.

milechainsaw
  • 274
  • 3
  • 8
2

You can use AsymmetricGridView and specify headers/footers with a bigger rowSpan so they would take the entire row.

Felipe Lima
  • 10,530
  • 4
  • 41
  • 39
1

You could use this library, http://tonicartos.github.io/StickyGridHeaders/

which allows you to create headers that are sticky (for grouping the list and keeping the header visible for the current group). You can turn off the sticky feature as well.

Matt Wolfe
  • 8,924
  • 8
  • 60
  • 77
1

There is a way to accomplish the desired functionality WITHOUT using a library or anything.

EDIT: Just borrow the HeaderGridView Implementation by google, see Here
You could also customize it for footer. The below suggestion is just too complicated and required more tweaking. Without going into specific details, all you need to do is this.

1) Subclass GridView
2) override onScrollChanged
3) Calculate the offset everytime it scrolls
4) Set the parentView(view that contains the headerView and gridview) translation y to -Offset.(view.setTranslationY(-offset). Also have an if statement to that once it reaches a certain offset it would stop scrolling.
5) obviously you want to structure this well so your gridview can have a method like attachToGridview(View view). I have a complete implementation of this which works.
See Scroll offset of GridView for help on getting offset since GridView has a bug were the views get recycled.

Community
  • 1
  • 1
Jessicardo
  • 826
  • 1
  • 8
  • 12
1

Why don't you change the appearance of the cells for the first rows? if you know how many columns you have, you know how many items will appear in the header = number of columns.It works for me

Guillaume
  • 2,912
  • 3
  • 35
  • 59
-2
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent"
              android:layout_height="fill_parent" android:orientation="vertical">

    <com.test.Breadcrumbs android:layout_width="fill_parent" android:layout_height="100dp" />

    <GridView
            android:id="@+id/grid"
            android:numColumns="auto_fit"
            android:gravity="center"
            android:stretchMode="columnWidth"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:verticalSpacing="10dp"
            android:horizontalSpacing="10dp">
    </GridView>

</LinearLayout>

and Breadcrumbs:

public class Breadcrumbs extends LinearLayout {

    public Breadcrumbs(final Context context, final AttributeSet attrs) {
        super(context, attrs);

        final LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        layoutView = inflater.inflate(R.layout.breadcrumbs, this, true);

works fine, scroll for grid works as well.

Alex Ivasyuv
  • 8,585
  • 17
  • 72
  • 90
  • 2
    Is this the same answer as @AntonChikin? Specifically, your Breadcrumbs stay fixed at the top while the grid scrolls beneath them right? The goal here is to incorporate a header at the top of the grid that scrolls along with the grid. – dokkaebi Nov 28 '12 at 00:28
  • this is not the point of the question, we want the header to scroll through – Rafael Sanches Sep 18 '13 at 08:14