Can a GridView have a footer and header just like ListView?
Asked Answered
V

11

26

A quick question:

In ListView I use this code:

list.addHeaderView(headerView);

How to deal with it when working on gridview?

Thanks.

Valeda answered 26/4, 2011 at 12:22 Comment(0)
S
32

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

Santalaceous answered 26/4, 2011 at 13:3 Comment(2)
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. :)Valeda
@Guru: Sorry, I am not aware of anything that will readily work for that. You cannot put a GridView in a ScrollView, for example.Santalaceous
J
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.

Jujutsu answered 16/1, 2014 at 9:2 Comment(10)
Works very well, thanks! Just have to be aware that it adds an additional item to your array adapter.Sosanna
Thanks! There is an issue with fast scroll, but I simply fixed it after minor changes: HeaderViewGridAdapter extends BaseAdapter in HeaderGridView.java.Celeski
Why does Google insist on having components that should be core hidden in their own applications?Confabulation
I agree, Google makes it bloody difficult to add style. It should be basic functionality to have a header and footer in a gridview !Pals
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 @Celeski said.Hypothesize
has anyone tweaked it for footer instead of header?Silvern
For views that need footer I used tonicartos.github.io/StickyGridHeaders .Jujutsu
@Celeski Can you explain a bit more. i have same issue, i changed my adapter to extend BaseAdapter instead of listAdapter and still having issueImmunogenetics
@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 ...'Celeski
HeaderGridView has couple of bugs!Dialectal
I
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>
Intoxicant answered 10/12, 2013 at 8:41 Comment(0)
M
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'
Meander answered 7/9, 2015 at 5:10 Comment(0)
S
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.

Shot answered 29/6, 2012 at 20:31 Comment(1)
You can get some of this work done for you by using HeaderViewListAdapter to wrap your existing adaptor. If you look at the source it's quite obvious how to use it.Farouche
D
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.

Draughtsman answered 7/1, 2014 at 20:35 Comment(0)
W
2

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

Waterlog answered 15/4, 2014 at 17:18 Comment(1)
Actually this one might do the job more easily: github.com/felipecsl/AbsListViewHelperWaterlog
R
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

Rafaellle answered 15/6, 2011 at 0:33 Comment(0)
M
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.

Madrigalist answered 27/3, 2014 at 19:41 Comment(0)
K
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.

Kilovoltampere answered 24/9, 2015 at 22:35 Comment(0)
C
-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.

Cordeiro answered 18/7, 2012 at 7:0 Comment(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.Angelaangele
this is not the point of the question, we want the header to scroll throughSpiker

© 2022 - 2024 — McMap. All rights reserved.