Reputation: 533
I have followed a few stackoverflow threads, tutorials and what I can gather from the documentation but just can't get the AplhabetIndexer
working in Android. The goal is to have an indexed ListView
that users can quickly scroll using the letters on the right as per the standard contacts app on your phone. Eventually I'll add section headers in the list and make it filterable as a user types but for now I just want to get the basic list working.
I can load the list and get all my results from the cursor, but I never get the letters appear on the right of the ListView
. I've tried different combinations of setting the adapter, including in the onCreateView
with a null cursor and then calling changeCursor(cursor)
in the onLoadFinished()
callback, as well as the current version below which sets up the adapter completely in the onLoadFinished()
callback.
Has anyone got a full working version of their setup and adapter code they could share? Preferably using the method of creating the adapter first, then just calling changeCursor(cursor)
in the onLoadFinished()
callback.
What I have so far:
StoreListAdapter.java
public class StoreListAdapter extends SimpleCursorAdapter implements SectionIndexer {
private AlphabetIndexer mAlphabetIndexer;
public StoreListAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
super(context, layout, cursor, from, to, flags);
if(cursor != null){
mAlphabetIndexer = new AlphabetIndexer(cursor,
cursor.getColumnIndex(StoreEntry.TABLE_ALIAS + StoreEntry.COLUMN_NAME),
"ABCDEFGHIJKLMNOPQRTSUVWXYZ");
mAlphabetIndexer.setCursor(cursor);
}
}
@Override
public void changeCursor(Cursor cursor) {
super.changeCursor(cursor);
if(cursor != null){
mAlphabetIndexer = new AlphabetIndexer(cursor,
cursor.getColumnIndex(StoreEntry.TABLE_ALIAS + StoreEntry.COLUMN_NAME),
"ABCDEFGHIJKLMNOPQRTSUVWXYZ");
mAlphabetIndexer.setCursor(cursor);
}
}
@Override
public Object[] getSections() {
if(mAlphabetIndexer != null){
return mAlphabetIndexer.getSections();
}else{
return null;
}
}
@Override
public int getPositionForSection(int sectionIndex) {
if(mAlphabetIndexer != null){
return mAlphabetIndexer.getPositionForSection(sectionIndex);
}else{
return 0;
}
}
@Override
public int getSectionForPosition(int position) {
if(mAlphabetIndexer != null){
return mAlphabetIndexer.getSectionForPosition(position);
}else{
return 0;
}
}
}
StoreListFragment.java
public class StoreListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private ListView mListView;
private StoreListAdapter mAdapter;
public static StoreListFragment newInstance() {
StoreListFragment fragment = new StoreListFragment();
return fragment;
}
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public StoreListFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getLoaderManager().initLoader(0, null, this);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_store_search, container, false);
mListView = (ListView) view.findViewById(R.id.search_result_list);
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
@Override
public void onDetach() {
super.onDetach();
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(
getActivity(), // Parent activity context
StoreProvider.CONTENT_URI, // Table to query
null, // Projection to return
null, // No selection clause
new String[]{getString(R.string.centre_id)}, // No selection arguments
null // Default sort order
);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mListView.setFastScrollEnabled(true);
mListView.setScrollingCacheEnabled(true);
mAdapter = new StoreListAdapter(getActivity().getApplicationContext(), R.layout.store_list_item, data, new
String[]{StoreEntry.TABLE_ALIAS + StoreEntry.COLUMN_NAME}, new int[]{R.id.item_name}, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
mListView.setAdapter(mAdapter);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.changeCursor(null);
}
}
Upvotes: 0
Views: 367
Reputation: 3560
The exact behavior can be found in class FastScroller
which is a helper class for AbsListView
. There is a piece of code there that decides if "the list is long"
final boolean longList = childCount > 0 && itemCount / childCount >= MIN_PAGES;
MIN_PAGES
is defined with value of 4. There you have it, if your list item count is not at least 4x the child count (visible rows) fast scroller and thus alphabet indexer will not appear.
Upvotes: 2
Reputation: 533
Actually, when I added more test data it started working. Would appear that if your search results are small (I was using about 20 or so) it doesn't kick in. Once I added some dummy data of about 100 or so then it started working.
Upvotes: 1