├── bin
├── headergridview.jar
├── res
│ ├── drawable-hdpi
│ │ └── ic_launcher.png
│ ├── drawable-mdpi
│ │ └── ic_launcher.png
│ └── drawable-xhdpi
│ │ └── ic_launcher.png
├── R.txt
├── classes
│ └── com
│ │ └── origamilabs
│ │ └── library
│ │ └── headergridview
│ │ ├── R.class
│ │ ├── R$attr.class
│ │ ├── R$style.class
│ │ ├── R$drawable.class
│ │ ├── R$string.class
│ │ ├── BuildConfig.class
│ │ └── views
│ │ └── HeaderGridView.class
└── AndroidManifest.xml
├── libs
└── android-support-v4.jar
├── res
├── values
│ ├── strings.xml
│ └── styles.xml
├── drawable-hdpi
│ └── ic_launcher.png
├── drawable-mdpi
│ └── ic_launcher.png
├── drawable-xhdpi
│ └── ic_launcher.png
├── values-v11
│ └── styles.xml
└── values-v14
│ └── styles.xml
├── gen
└── com
│ └── origamilabs
│ └── library
│ └── headergridview
│ ├── BuildConfig.java
│ └── R.java
├── .classpath
├── AndroidManifest.xml
├── project.properties
├── proguard-project.txt
├── .project
├── README.md
└── src
└── com
└── origamilabs
└── library
└── headergridview
└── views
└── HeaderGridView.java
/bin/headergridview.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/headergridview.jar
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | HeaderGridView
4 |
5 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bin/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bin/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bin/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/bin/R.txt:
--------------------------------------------------------------------------------
1 | int drawable ic_launcher 0x7f020000
2 | int string app_name 0x7f030000
3 | int style AppBaseTheme 0x7f040000
4 | int style AppTheme 0x7f040001
5 |
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/R.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/R.class
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/R$attr.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/R$attr.class
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/R$style.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/R$style.class
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/R$drawable.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/R$drawable.class
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/R$string.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/R$string.class
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/BuildConfig.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/BuildConfig.class
--------------------------------------------------------------------------------
/bin/classes/com/origamilabs/library/headergridview/views/HeaderGridView.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/maurycyw/HeaderGridView/HEAD/bin/classes/com/origamilabs/library/headergridview/views/HeaderGridView.class
--------------------------------------------------------------------------------
/gen/com/origamilabs/library/headergridview/BuildConfig.java:
--------------------------------------------------------------------------------
1 | /** Automatically generated file. DO NOT MODIFY */
2 | package com.origamilabs.library.headergridview;
3 |
4 | public final class BuildConfig {
5 | public final static boolean DEBUG = true;
6 | }
--------------------------------------------------------------------------------
/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/bin/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
9 |
10 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system edit
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 | #
10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
12 |
13 | # Project target.
14 | target=android-17
15 | android.library=true
16 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
--------------------------------------------------------------------------------
/proguard-project.txt:
--------------------------------------------------------------------------------
1 | # To enable ProGuard in your project, edit project.properties
2 | # to define the proguard.config property as described in that file.
3 | #
4 | # Add project specific ProGuard rules here.
5 | # By default, the flags in this file are appended to flags specified
6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt
7 | # You can edit the include path and order by changing the ProGuard
8 | # include property in project.properties.
9 | #
10 | # For more details, see
11 | # http://developer.android.com/guide/developing/tools/proguard.html
12 |
13 | # Add any project specific keep options here:
14 |
15 | # If your project uses WebView with JS, uncomment the following
16 | # and specify the fully qualified class name to the JavaScript interface
17 | # class:
18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
19 | # public *;
20 | #}
21 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | HeaderGridView
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | HeaderGridView
2 | =======
3 |
4 | ## Introduction
5 |
6 | This is an updated version of GridView which allows for Headers. The Headers themselves are not part of the adapter / data source. This means that the headers only are not being recycled.
7 |
8 | ## Setup
9 |
10 | To use HeaderGridView in your projects, simply add this project to your workspace then add it as a library project to your current project.
11 |
12 | ## Usage
13 |
14 | HeaderGridView can be added as a custom view to any layout.
15 |
16 | instead of ``` ``` use…
17 | ```xml
18 |
19 | ```
20 | then simply add header views via
21 | ```xml
22 | // same methods as ListView
23 | addHeaderView(View v, Object data, boolean isSelectable);
24 | addHeaderView(View v);
25 | ```
26 |
27 | ## Tests
28 |
29 | None.
30 |
31 |
32 | ## TODO:
33 |
34 | * implement Footer support. should be simple
35 | * develop tests
36 |
37 |
--------------------------------------------------------------------------------
/gen/com/origamilabs/library/headergridview/R.java:
--------------------------------------------------------------------------------
1 | /* AUTO-GENERATED FILE. DO NOT MODIFY.
2 | *
3 | * This class was automatically generated by the
4 | * aapt tool from the resource data it found. It
5 | * should not be modified by hand.
6 | */
7 |
8 | package com.origamilabs.library.headergridview;
9 |
10 | public final class R {
11 | public static final class attr {
12 | }
13 | public static final class drawable {
14 | public static int ic_launcher=0x7f020000;
15 | }
16 | public static final class string {
17 | public static int app_name=0x7f030000;
18 | }
19 | public static final class style {
20 | /**
21 | Base application theme, dependent on API level. This theme is replaced
22 | by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
23 |
24 |
25 | Theme customizations available in newer API levels can go in
26 | res/values-vXX/styles.xml, while customizations related to
27 | backward-compatibility can go here.
28 |
29 |
30 | Base application theme for API 11+. This theme completely replaces
31 | AppBaseTheme from res/values/styles.xml on API 11+ devices.
32 |
33 | API 11 theme customizations can go here.
34 |
35 | Base application theme for API 14+. This theme completely replaces
36 | AppBaseTheme from BOTH res/values/styles.xml and
37 | res/values-v11/styles.xml on API 14+ devices.
38 |
39 | API 14 theme customizations can go here.
40 | */
41 | public static int AppBaseTheme=0x7f040000;
42 | /** Application theme.
43 | All customizations that are NOT specific to a particular API-level can go here.
44 | */
45 | public static int AppTheme=0x7f040001;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/origamilabs/library/headergridview/views/HeaderGridView.java:
--------------------------------------------------------------------------------
1 | package com.origamilabs.library.headergridview.views;
2 |
3 |
4 | import java.util.ArrayList;
5 |
6 | import android.app.Activity;
7 | import android.content.Context;
8 | import android.graphics.Canvas;
9 | import android.util.AttributeSet;
10 | import android.util.DisplayMetrics;
11 | import android.view.View;
12 | import android.widget.AbsListView;
13 | import android.widget.AbsListView.OnScrollListener;
14 | import android.widget.GridView;
15 | import android.widget.ListAdapter;
16 | import android.widget.ListView;
17 | import android.widget.ListView.FixedViewInfo;
18 |
19 | public class HeaderGridView extends GridView implements OnScrollListener{
20 |
21 | private ListAdapter mAdapter;
22 | private boolean mShowHeader = false;
23 | private Context mContext;
24 | private int mScrollOfsset;
25 | private int initialTopPadding;
26 | private int mDisplayWidth = 0;
27 |
28 | public HeaderGridView(Context context, AttributeSet attrs, int defStyle) {
29 | super(context, attrs, defStyle);
30 | init(context);
31 | }
32 |
33 | public HeaderGridView(Context context, AttributeSet attrs) {
34 | super(context, attrs);
35 | init(context);
36 | }
37 |
38 | public HeaderGridView(Context context) {
39 | super(context);
40 | init(context);
41 | }
42 |
43 | private void init(Context context){
44 | mContext = context;
45 | super.setOnScrollListener(this);
46 | }
47 | /**
48 | * A class that represents a fixed view in a list, for example a header at the top
49 | * or a footer at the bottom.
50 | */
51 |
52 | private ArrayList mHeaderViewInfos = new ArrayList();
53 | // TODO: add in footer view support. pull request someone?
54 | private ArrayList mFooterViewInfos = new ArrayList();
55 |
56 | private void notifiyChanged(){
57 | this.requestLayout();
58 | this.invalidate();
59 | }
60 |
61 | public void addHeaderView(View v, Object data, boolean isSelectable) {
62 |
63 | FixedViewInfo info = new ListView(getContext()).new FixedViewInfo();
64 | info.view = v;
65 | info.data = data;
66 | info.isSelectable = isSelectable;
67 | mHeaderViewInfos.add(info);
68 |
69 | setupView(v);
70 |
71 | int topPadding = this.getPaddingTop();
72 | if(initialTopPadding == 0){
73 | initialTopPadding = topPadding;
74 | }
75 | this.setPadding(this.getPaddingLeft(), topPadding+v.getMeasuredHeight(), this.getPaddingRight(), this.getPaddingBottom());
76 |
77 | // in the case of re-adding a header view, or adding one later on,
78 | // we need to notify the observer
79 | this.notifiyChanged();
80 | }
81 |
82 | private void setupView(View v){
83 | // in my application the views are merely just inflated... because of this measure and layout need to be called
84 |
85 | boolean isLayedOut = !((v.getRight()==0) && (v.getLeft()==0) && (v.getTop()==0) && (v.getBottom()==0));
86 |
87 | // no need to do this more than nce per view. Sometimes people repeat headers.
88 | if(v.getMeasuredHeight() != 0 && isLayedOut ) return;
89 |
90 | if(mDisplayWidth == 0){
91 | DisplayMetrics displaymetrics = new DisplayMetrics();
92 | ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
93 | mDisplayWidth = displaymetrics.widthPixels;
94 | }
95 |
96 | v.measure(MeasureSpec.makeMeasureSpec(mDisplayWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
97 | v.layout(0, getTotalHeaderHeight(), v.getMeasuredWidth(), getTotalHeaderHeight() + v.getMeasuredHeight());
98 | }
99 |
100 | public void addHeaderView(View v) {
101 | this.addHeaderView(v, null, false);
102 | }
103 |
104 | private void drawHeaders(Canvas canvas) {
105 | int startPos = -mScrollOfsset; // translate view all way up first...
106 | int saveCount = canvas.save();
107 | for(FixedViewInfo header: mHeaderViewInfos){
108 | View view = header.view;
109 | canvas.translate(0, startPos);
110 | startPos = view.getMeasuredHeight();
111 | view.draw(canvas);
112 | }
113 | canvas.restoreToCount(saveCount);
114 | }
115 |
116 | @Override
117 | protected void dispatchDraw(Canvas canvas) {
118 | super.dispatchDraw(canvas);
119 | drawHeaders(canvas);
120 | }
121 |
122 | private void invalidateIfAnimating() {
123 | invalidate();
124 | }
125 |
126 | public int getHeaderViewCount(){
127 | return mHeaderViewInfos.size();
128 | }
129 |
130 | private int getTotalHeaderHeight(){
131 | int totalHeaderHeight = 0;
132 | for(FixedViewInfo h: mHeaderViewInfos){
133 | totalHeaderHeight += h.view.getMeasuredHeight();
134 | }
135 | return totalHeaderHeight;
136 | }
137 |
138 | @Override
139 | public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
140 | if(this.getAdapter()!=null){
141 | int count = this.getChildCount();
142 | int totalHeaderHeight = getTotalHeaderHeight();
143 |
144 | if(count > 0 && firstVisibleItem == 0){
145 | View child = this.getChildAt(0);
146 | mScrollOfsset = totalHeaderHeight - child.getTop() + initialTopPadding;
147 |
148 | // need to check to see if should show header
149 | // no need to dispatch otherwise
150 | if(child.getTop() >= 0){
151 | mShowHeader = true;
152 | }else{
153 | mShowHeader = false;
154 | }
155 | }else{
156 | mShowHeader = false;
157 | }
158 |
159 | if(mShowHeader){
160 | this.invalidateIfAnimating();
161 | }
162 | }
163 |
164 | }
165 |
166 | /**
167 | * Remove the view and return true is a view has been removed.
168 | * @param v
169 | * @return
170 | */
171 | public boolean removeHeaderView(View v) {
172 | if (mHeaderViewInfos.size() > 0) {
173 | return removeFixedViewInfo(v, mHeaderViewInfos);
174 | }
175 | return false;
176 | }
177 |
178 | private boolean removeFixedViewInfo(View v, ArrayList where) {
179 | int len = where.size();
180 | int count = 0;
181 | for (int i = 0; i < len; ++i) {
182 | FixedViewInfo info = where.get(i);
183 | if (info.view == v) {
184 | this.setPadding(this.getPaddingLeft(), getPaddingTop()-v.getMeasuredHeight(), this.getPaddingRight(), this.getPaddingBottom());
185 | where.remove(i);
186 | count++;
187 | break;
188 | }
189 | }
190 |
191 | return count > 0;
192 | }
193 |
194 | @Override
195 | public void onScrollStateChanged(AbsListView view, int scrollState) {
196 | }
197 | }
198 |
--------------------------------------------------------------------------------