Skip to content
This repository has been archived by the owner on Jun 9, 2020. It is now read-only.

Commit

Permalink
Supporting list headers and footers
Browse files Browse the repository at this point in the history
  • Loading branch information
beworker committed Nov 15, 2013
1 parent f28ab73 commit 850dda7
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
6 changes: 6 additions & 0 deletions example/res/menu/main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,11 @@
android:showAsAction="never"
android:title="@string/action_showShadow"
android:checkable="true"/>

<item
android:id="@+id/action_showHeaderAndFooter"
android:showAsAction="never"
android:title="@string/action_showHeaderAndFooter"
android:checkable="true"/>

</menu>
1 change: 1 addition & 0 deletions example/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
<string name="action_fastscroll">Fast scroll</string>
<string name="action_addpadding">Add padding</string>
<string name="action_showShadow">Show shadow</string>
<string name="action_showHeaderAndFooter">Show Header &amp; Footer</string>

</resources>
42 changes: 39 additions & 3 deletions example/src/com/hb/examples/PinnedSectionListActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SectionIndexer;
import android.widget.TextView;
Expand Down Expand Up @@ -161,6 +163,7 @@ public Item(int type, String text) {

}

private boolean hasHeaderAndFooter;
private boolean isFastScroll;
private boolean addPadding;
private boolean isShadowVisible = true;
Expand All @@ -173,23 +176,30 @@ protected void onCreate(Bundle savedInstanceState) {
isFastScroll = savedInstanceState.getBoolean("isFastScroll");
addPadding = savedInstanceState.getBoolean("addPadding");
isShadowVisible = savedInstanceState.getBoolean("isShadowVisible");
hasHeaderAndFooter = savedInstanceState.getBoolean("hasHeaderAndFooter");
}
initializeHeaderAndFooter();
initializeAdapter();
initializePadding();
}

@Override
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("isFastScroll", isFastScroll);
outState.putBoolean("addPadding", addPadding);
outState.putBoolean("isShadowVisible", isShadowVisible);
outState.putBoolean("hasHeaderAndFooter", hasHeaderAndFooter);
}

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
Item item = (Item) getListAdapter().getItem(position);
Toast.makeText(this, "Item " + position + ": " + item.text, Toast.LENGTH_SHORT).show();
Item item = (Item) getListView().getAdapter().getItem(position);
if (item != null) {
Toast.makeText(this, "Item " + position + ": " + item.text, Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Item " + position, Toast.LENGTH_SHORT).show();
}
}

@Override
Expand Down Expand Up @@ -219,6 +229,11 @@ public boolean onOptionsItemSelected(MenuItem item) {
item.setChecked(isShadowVisible);
((PinnedSectionListView)getListView()).setShadowVisible(isShadowVisible);
break;
case R.id.action_showHeaderAndFooter:
hasHeaderAndFooter = !hasHeaderAndFooter;
item.setChecked(hasHeaderAndFooter);
initializeHeaderAndFooter();
break;
}
return true;
}
Expand All @@ -229,6 +244,27 @@ private void initializePadding() {
getListView().setPadding(padding, padding, padding, padding);
}

private void initializeHeaderAndFooter() {
setListAdapter(null);
if (hasHeaderAndFooter) {
ListView list = getListView();

LayoutInflater inflater = LayoutInflater.from(this);
TextView header1 = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, list, false);
header1.setText("First header");
list.addHeaderView(header1);

TextView header2 = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, list, false);
header2.setText("Second header");
list.addHeaderView(header2);

TextView footer = (TextView) inflater.inflate(android.R.layout.simple_list_item_1, list, false);
footer.setText("Single foolter");
list.addFooterView(footer);
}
initializeAdapter();
}

@SuppressLint("NewApi")
private void initializeAdapter() {
getListView().setFastScrollEnabled(isFastScroll);
Expand Down
22 changes: 15 additions & 7 deletions library/src/com/hb/views/PinnedSectionListView.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AbsListView;
import android.widget.HeaderViewListAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SectionIndexer;
Expand Down Expand Up @@ -101,11 +102,11 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun
}

// get expected adapter or fail fast
PinnedSectionListAdapter adapter = (PinnedSectionListAdapter) view.getAdapter();
ListAdapter adapter = getAdapter();
if (adapter == null || visibleItemCount == 0) return; // nothing to do

final boolean isFirstVisibleItemSection =
adapter.isItemViewTypePinned(adapter.getItemViewType(firstVisibleItem));
isItemViewTypePinned(adapter, adapter.getItemViewType(firstVisibleItem));

if (isFirstVisibleItemSection) {
View sectionView = getChildAt(0);
Expand Down Expand Up @@ -275,33 +276,33 @@ void ensureShadowForPosition(int sectionPosition, int firstVisibleItem, int visi
}

int findFirstVisibleSectionPosition(int firstVisibleItem, int visibleItemCount) {
PinnedSectionListAdapter adapter = (PinnedSectionListAdapter) getAdapter();
ListAdapter adapter = getAdapter();
for (int childIndex = 0; childIndex < visibleItemCount; childIndex++) {
int position = firstVisibleItem + childIndex;
int viewType = adapter.getItemViewType(position);
if (adapter.isItemViewTypePinned(viewType)) return position;
if (isItemViewTypePinned(adapter, viewType)) return position;
}
return -1;
}

int findCurrentSectionPosition(int fromPosition) {
PinnedSectionListAdapter adapter = (PinnedSectionListAdapter) getAdapter();
ListAdapter adapter = getAdapter();

if (adapter instanceof SectionIndexer) {
// try fast way by asking section indexer
SectionIndexer indexer = (SectionIndexer) adapter;
int sectionPosition = indexer.getSectionForPosition(fromPosition);
int itemPosition = indexer.getPositionForSection(sectionPosition);
int typeView = adapter.getItemViewType(itemPosition);
if (adapter.isItemViewTypePinned(typeView)) {
if (isItemViewTypePinned(adapter, typeView)) {
return itemPosition;
} // else, no luck
}

// try slow way by looking through to the next section item above
for (int position=fromPosition; position>=0; position--) {
int viewType = adapter.getItemViewType(position);
if (adapter.isItemViewTypePinned(viewType)) return position;
if (isItemViewTypePinned(adapter, viewType)) return position;
}
return -1; // no candidate found
}
Expand Down Expand Up @@ -502,4 +503,11 @@ private boolean performPinnedItemClick() {
return false;
}

public static boolean isItemViewTypePinned(ListAdapter adapter, int viewType) {
if (adapter instanceof HeaderViewListAdapter) {
adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
}
return ((PinnedSectionListAdapter) adapter).isItemViewTypePinned(viewType);
}

}

0 comments on commit 850dda7

Please sign in to comment.