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

Bug: Fixes Item not staying pinned #94

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ public class PinnedSectionListActivity extends ListActivity implements OnClickLi

static class SimpleAdapter extends ArrayAdapter<Item> implements PinnedSectionListAdapter {

int currentPinned;
int headerItems;

private static final int[] COLORS = new int[] {
R.color.green_light, R.color.orange_light,
R.color.blue_light, R.color.red_light };

public SimpleAdapter(Context context, int resource, int textViewResourceId) {
public SimpleAdapter(Context context, int resource, int textViewResourceId, int headerItems) {
super(context, resource, textViewResourceId);
generateDataset('A', 'Z', false);
this.headerItems = headerItems;
}

public void generateDataset(char from, char to, boolean clear) {
Expand Down Expand Up @@ -90,7 +94,12 @@ protected void onSectionAdded(Item section, int sectionPosition) { }
Item item = getItem(position);
if (item.type == Item.SECTION) {
//view.setOnClickListener(PinnedSectionListActivity.this);
view.setBackgroundColor(parent.getResources().getColor(COLORS[item.sectionPosition % COLORS.length]));
// If there are header Views, the position received does not include these
if(highlightActive && (position + headerItems) == currentPinned) {
view.setBackgroundColor(parent.getResources().getColor(R.color.pink_light));
} else {
view.setBackgroundColor(parent.getResources().getColor(COLORS[item.sectionPosition % COLORS.length]));
}
}
return view;
}
Expand All @@ -108,14 +117,23 @@ public boolean isItemViewTypePinned(int viewType) {
return viewType == Item.SECTION;
}

@Override
public void pinnedItemChanged(int position) {
// Record the current pinned item and redraw
if(highlightActive) {
currentPinned = position;
notifyDataSetChanged();
}
}

}

static class FastScrollAdapter extends SimpleAdapter implements SectionIndexer {

private Item[] sections;

public FastScrollAdapter(Context context, int resource, int textViewResourceId) {
super(context, resource, textViewResourceId);
public FastScrollAdapter(Context context, int resource, int textViewResourceId, int headerItems) {
super(context, resource, textViewResourceId, headerItems);
}

@Override protected void prepareSections(int sectionsNumber) {
Expand Down Expand Up @@ -172,6 +190,7 @@ public Item(int type, String text) {
private boolean isFastScroll;
private boolean addPadding;
private boolean isShadowVisible = true;
private static boolean highlightActive = false;
private int mDatasetUpdateCount;

@Override
Expand All @@ -183,6 +202,7 @@ protected void onCreate(Bundle savedInstanceState) {
addPadding = savedInstanceState.getBoolean("addPadding");
isShadowVisible = savedInstanceState.getBoolean("isShadowVisible");
hasHeaderAndFooter = savedInstanceState.getBoolean("hasHeaderAndFooter");
highlightActive = savedInstanceState.getBoolean("highlightActive");
}
initializeHeaderAndFooter();
initializeAdapter();
Expand All @@ -196,6 +216,7 @@ protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean("addPadding", addPadding);
outState.putBoolean("isShadowVisible", isShadowVisible);
outState.putBoolean("hasHeaderAndFooter", hasHeaderAndFooter);
outState.putBoolean("highlightActive", highlightActive);
}

@Override
Expand All @@ -214,6 +235,7 @@ public boolean onCreateOptionsMenu(Menu menu) {
menu.getItem(0).setChecked(isFastScroll);
menu.getItem(1).setChecked(addPadding);
menu.getItem(2).setChecked(isShadowVisible);
menu.getItem(3).setChecked(highlightActive);
return true;
}

Expand All @@ -240,6 +262,10 @@ public boolean onOptionsItemSelected(MenuItem item) {
item.setChecked(hasHeaderAndFooter);
initializeHeaderAndFooter();
break;
case R.id.action_highlight_active:
highlightActive = !highlightActive;
item.setChecked(highlightActive);
break;
case R.id.action_updateDataset:
updateDataset();
break;
Expand Down Expand Up @@ -293,9 +319,9 @@ private void initializeAdapter() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getListView().setFastScrollAlwaysVisible(true);
}
setListAdapter(new FastScrollAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1));
setListAdapter(new FastScrollAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1, getListView().getHeaderViewsCount()));
} else {
setListAdapter(new SimpleAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1));
setListAdapter(new SimpleAdapter(this, android.R.layout.simple_list_item_1, android.R.id.text1, getListView().getHeaderViewsCount()));
}
}

Expand Down
6 changes: 6 additions & 0 deletions example/src/main/res/menu/main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
android:title="@string/action_showHeaderAndFooter"
android:checkable="true"/>

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

<item
android:id="@+id/action_updateDataset"
android:showAsAction="never"
Expand Down
3 changes: 2 additions & 1 deletion example/src/main/res/values/colors.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
<color name="green_light">#ff99cc00</color>
<color name="orange_light">#ffffbb33</color>
<color name="blue_light">#ff33b5e5</color>

<color name="pink_light">#ffff00fc</color>

<!-- Went to: $android-sdk > Android:v14 > res > values > colors.xml and copied the colors-->

</resources>
1 change: 1 addition & 0 deletions example/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
<string name="action_showShadow">Show shadow</string>
<string name="action_showHeaderAndFooter">Show Header &amp; Footer</string>
<string name="action_updateDataset">Update dataset</string>
<string name="action_highlight_active">Highlight active item</string>

</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public class PinnedSectionListView extends ListView {
public interface PinnedSectionListAdapter extends ListAdapter {
/** This method shall return 'true' if views of given type has to be pinned. */
boolean isItemViewTypePinned(int viewType);
/** This method notifies the adapter that the pinned item has changed. */
void pinnedItemChanged(int position);
}

/** Wrapper class for pinned section view and its position in the list. */
Expand Down Expand Up @@ -84,6 +86,9 @@ static class PinnedSection {
/** Pinned view Y-translation. We use it to stick pinned view to the next section. */
int mTranslateY;

/** Position of the current pinned item, so we can tell when it changes. */
int currentPinned;

/** Scroll listener which does the magic */
private final OnScrollListener mOnScrollListener = new OnScrollListener() {

Expand All @@ -104,6 +109,8 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun
ListAdapter adapter = getAdapter();
if (adapter == null || visibleItemCount == 0) return; // nothing to do

int sectionPosition = findCurrentSectionPosition(firstVisibleItem);

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

Expand All @@ -116,7 +123,6 @@ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCoun
}

} else { // section is not at the first visible position
int sectionPosition = findCurrentSectionPosition(firstVisibleItem);
if (sectionPosition > -1) { // we have section position
ensureShadowForPosition(sectionPosition, firstVisibleItem, visibleItemCount);
} else { // there is no section for the first visible item, destroy shadow
Expand Down Expand Up @@ -236,10 +242,6 @@ void destroyPinnedShadow() {

/** Makes sure we have an actual pinned shadow for given position. */
void ensureShadowForPosition(int sectionPosition, int firstVisibleItem, int visibleItemCount) {
if (visibleItemCount < 2) { // no need for creating shadow at all, we have a single visible item
destroyPinnedShadow();
return;
}

if (mPinnedSection != null
&& mPinnedSection.position != sectionPosition) { // invalidate shadow, if required
Expand Down Expand Up @@ -305,18 +307,30 @@ int findCurrentSectionPosition(int fromPosition) {
int itemPosition = indexer.getPositionForSection(sectionPosition);
int typeView = adapter.getItemViewType(itemPosition);
if (isItemViewTypePinned(adapter, typeView)) {
checkPinnedItemChange(adapter, itemPosition);
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 (isItemViewTypePinned(adapter, viewType)) return position;
if (isItemViewTypePinned(adapter, viewType)) {
checkPinnedItemChange(adapter, position);
return position;
}
}
return -1; // no candidate found
}

/* If the current item has changed, notify the adapter by calling its interface method. */
void checkPinnedItemChange(ListAdapter adapter, int position) {
if(currentPinned != position) {
currentPinned = position;
pinnedItemChanged(adapter, position);
}
}

void recreatePinnedShadow() {
destroyPinnedShadow();
ListAdapter adapter = getAdapter();
Expand Down Expand Up @@ -520,4 +534,11 @@ public static boolean isItemViewTypePinned(ListAdapter adapter, int viewType) {
return ((PinnedSectionListAdapter) adapter).isItemViewTypePinned(viewType);
}

public static void pinnedItemChanged(ListAdapter adapter, int position) {
if (adapter instanceof HeaderViewListAdapter) {
adapter = ((HeaderViewListAdapter)adapter).getWrappedAdapter();
}
((PinnedSectionListAdapter) adapter).pinnedItemChanged(position);
}

}