Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android : sample implementation of google's headergridview

I searched the Web and couldn't find anything but the source code of the class. I am still a beginner and I don't exactly understand how this class should be implemented

https://android.googlesource.com/platform/packages/apps/Gallery2/+/idea133/src/com/android/photos/views/HeaderGridView.java

Can someone provide me a coded implementation of such a class, say two headers, 4 views by header, one top header (above the grid view) , one bottom footer (below the grid view), as well as a demonstration of how to implement the filterable? (say by text within the view)

Thanks a lot

like image 843
Stephane Maarek Avatar asked Oct 20 '14 13:10

Stephane Maarek


1 Answers

package com.paging.gridview;




import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ListAdapter;


import java.util.ArrayList;


public class HeaderGridView extends GridView {


    private ListAdapter mAdapter;
    private Context mContext;


    /**
     * Should be used by subclasses to listen to changes in the dataset
     */
//  AdapterDataSetObserver mDataSetObserver;

    public HeaderGridView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }


    public HeaderGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }


    public HeaderGridView(Context context) {
        super(context);
        init(context);
    }

    private void init(Context context){
        mContext = context;
//      super.setOnScrollListener(this);
    }
    /**
     * A class that represents a fixed view in a list, for example a header at the top
     * or a footer at the bottom.
     */

    private ArrayList<FixedViewInfo> mHeaderViewInfos = new ArrayList<FixedViewInfo>();
    private ArrayList<FixedViewInfo> mFooterViewInfos = new ArrayList<FixedViewInfo>();

    private void notifiyChanged(){
        this.requestLayout();
        this.invalidate();
    }




    /**
     * Add a fixed view to appear at the top of the list. If this method is
     * called more than once, the views will appear in the order they were
     * added. Views added using this call can take focus if they want.
     * <p>
     * Note: When first introduced, this method could only be called before
     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
     * called at any time. If the ListView's adapter does not extend
     * {@link FooterViewGridAdapter}, it will be wrapped with a supporting
     * instance of {@link android.widget.WrapperListAdapter}.
     *
     * @param v The view to add.
     * @param data Data to associate with this view
     * @param isSelectable whether the item is selectable
     */
    public void addHeaderView(View v, Object data, boolean isSelectable) {
        final FixedViewInfo info = new FixedViewInfo();
        FrameLayout fl = new FullWidthFixedViewLayout(getContext());
        fl.addView(v);
        info.view = v;
        info.viewContainer = fl;
        info.data = data;
        info.isSelectable = isSelectable;
        mHeaderViewInfos.add(info);


        // Wrap the adapter if it wasn't already wrapped.
        if (mAdapter != null) {
            if (!(mAdapter instanceof FooterViewGridAdapter)) {
                mAdapter = new FooterViewGridAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
            }


            // Do not know if this really helps
            notifiyChanged();
        }
    }






    /**
     * Add a fixed view to appear at the top of the list. If addHeaderView is
     * called more than once, the views will appear in the order they were
     * added. Views added using this call can take focus if they want.
     * <p>
     * Note: When first introduced, this method could only be called before
     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
     * called at any time. If the ListView's adapter does not extend
     * {@link FooterViewGridAdapter}, it will be wrapped with a supporting
     * instance of {@link android.widget.WrapperListAdapter}.
     *
     * @param v The view to add.
     */
    public void addHeaderView(View v) {
        addHeaderView(v, null, true);
    }


    public int getHeaderViewsCount() {
        return mHeaderViewInfos.size();
    }


    /**
     * Add a fixed view to appear at the bottom of the list. If addFooterView is
     * called more than once, the views will appear in the order they were
     * added. Views added using this call can take focus if they want.
     * <p>
     * Note: When first introduced, this method could only be called before
     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
     * called at any time. If the ListView's adapter does not extend
     * {@link FooterViewGridAdapter}, it will be wrapped with a supporting
     * instance of {@link android.widget.WrapperListAdapter}.
     *
     * @param v The view to add.
     * @param data Data to associate with this view
     * @param isSelectable true if the footer view can be selected
     */
    public void addFooterView(View v, Object data, boolean isSelectable) {
        final FixedViewInfo info = new FixedViewInfo();
        FrameLayout fl = new FullWidthFixedViewLayout(getContext());
        fl.addView(v);
        info.view = v;
        info.viewContainer = fl;
        info.data = data;
        info.isSelectable = isSelectable;
        mFooterViewInfos.add(info);


        // Wrap the adapter if it wasn't already wrapped.
        if (mAdapter != null) {
            if (!(mAdapter instanceof FooterViewGridAdapter)) {
                mAdapter = new FooterViewGridAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
            }


            // Do not know if this really helps
            notifiyChanged();
        }
    }


    /**
     * Add a fixed view to appear at the bottom of the list. If addFooterView is
     * called more than once, the views will appear in the order they were
     * added. Views added using this call can take focus if they want.
     * <p>
     * Note: When first introduced, this method could only be called before
     * setting the adapter with {@link #setAdapter(ListAdapter)}. Starting with
     * {@link android.os.Build.VERSION_CODES#KITKAT}, this method may be
     * called at any time. If the ListView's adapter does not extend
     * {@link FooterViewGridAdapter}, it will be wrapped with a supporting
     * instance of {@link android.widget.WrapperListAdapter}.
     *
     * @param v The view to add.
     */
    public void addFooterView(View v) {
        addFooterView(v, null, true);
    }


    public int getFooterViewsCount() {
        return mFooterViewInfos.size();
    }


    /**
     * Removes a previously-added footer view.
     *
     * @param v The view to remove
     * @return
     * true if the view was removed, false if the view was not a footer view
     */
    public boolean removeFooterView(View v) {
        if (mFooterViewInfos.size() > 0) {
            boolean result = false;
            if (mAdapter != null && ((FooterViewGridAdapter) mAdapter).removeFooter(v)) {
                notifiyChanged();
                result = true;
            }
            removeFixedViewInfo(v, mFooterViewInfos);
            return result;
        }
        return false;
    }


    private void removeFixedViewInfo(View v, ArrayList<FixedViewInfo> where) {
        int len = where.size();
        for (int i = 0; i < len; ++i) {
            FixedViewInfo info = where.get(i);
            if (info.view == v) {
                where.remove(i);
                break;
            }
        }
    }




    @Override
    public void setAdapter(ListAdapter adapter) {
        this.mAdapter = adapter;


        if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new FooterViewGridAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
        } else {
            mAdapter = adapter;
        }


        super.setAdapter(adapter);
        super.setAdapter(this.mAdapter);


        requestLayout();
    }


    @Override
    public ListAdapter getAdapter() {
        return this.mAdapter;
    }


    public class FixedViewInfo {
        public android.view.View view;
        public ViewGroup viewContainer;
        public java.lang.Object data;
        public boolean isSelectable;
    }


    private class FullWidthFixedViewLayout extends FrameLayout {
        public FullWidthFixedViewLayout(Context context) {
            super(context);
        }


        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
            int targetWidth = HeaderGridView.this.getMeasuredWidth()
                - HeaderGridView.this.getPaddingLeft()
                - HeaderGridView.this.getPaddingRight();
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(targetWidth,
                MeasureSpec.getMode(widthMeasureSpec));
            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        }
    }
}

Link to project https://github.com/nicolasjafelle/PagingGridView/blob/master/PagingGridViewProject/PagingGridView/src/main/java/com/paging/gridview/HeaderGridView.java

like image 132
AZ_ Avatar answered Oct 21 '22 20:10

AZ_