AlphabetIndexer con adaptador personalizado administrado por LoaderManager

Estoy tratando de implementar AlphabetIndexer con un adaptador personalizado como este

AlphabetIndexer con adaptador personalizado

Mi clase ContactsCursorAdapter extiende SimpleCursorAdapter e implementa SectionIndexer y estoy usando un LoaderManager para administrar el cursor de mi adaptador, así que he reemplazado el método swapCursor() como lo indica la segunda respuesta al ejemplo anterior.

 public class ContactsCursorAdapter extends SimpleCursorAdapter implements SectionIndexer{ private LayoutInflater mInflater; private Context mContext; private AlphabetIndexer mAlphaIndexer; public ContactsCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to); mInflater = LayoutInflater.from(context); mContext = context; } public View getView(final int position, View convertView, ViewGroup parent) { ... } @Override public int getPositionForSection(int section) { return mAlphaIndexer.getPositionForSection(section); } @Override public int getSectionForPosition(int position) { return mAlphaIndexer.getSectionForPosition(position); } @Override public Object[] getSections() { return mAlphaIndexer.getSections(); } public Cursor swapCursor(Cursor c) { // Create our indexer if (c != null) { mAlphaIndexer = new AlphabetIndexer(c, c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME), " ABCDEFGHIJKLMNOPQRSTUVWXYZ"); } return super.swapCursor(c); } } 

Sin embargo, esto se descarta si configuro mi listview para fastScrollEnabled = true

getListView (). setFastScrollEnabled (true);

en mi clase ContactsCursorLoaderListFragment que extiende ListFragment e implementa LoaderManager.LoaderCallbacks.

Aquí está el rastro de la stack:

 04-25 01:37:23.280: E/AndroidRuntime(711): FATAL EXCEPTION: main 04-25 01:37:23.280: E/AndroidRuntime(711): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.sendit/com.sendit.ContactManager}: java.lang.NullPointerException 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1956) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.ActivityThread.access$600(ActivityThread.java:123) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.os.Handler.dispatchMessage(Handler.java:99) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.os.Looper.loop(Looper.java:137) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.ActivityThread.main(ActivityThread.java:4424) 04-25 01:37:23.280: E/AndroidRuntime(711): at java.lang.reflect.Method.invokeNative(Native Method) 04-25 01:37:23.280: E/AndroidRuntime(711): at java.lang.reflect.Method.invoke(Method.java:511) 04-25 01:37:23.280: E/AndroidRuntime(711): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 04-25 01:37:23.280: E/AndroidRuntime(711): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 04-25 01:37:23.280: E/AndroidRuntime(711): at dalvik.system.NativeStart.main(Native Method) 04-25 01:37:23.280: E/AndroidRuntime(711): Caused by: java.lang.NullPointerException 04-25 01:37:23.280: E/AndroidRuntime(711): at com.sendit.ContactsCursorAdapter.getSections(ContactsCursorAdapter.java:222) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.widget.FastScroller.getSectionsFromIndexer(FastScroller.java:507) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.widget.FastScroller.init(FastScroller.java:269) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.widget.FastScroller.(FastScroller.java:155) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.widget.AbsListView.setFastScrollEnabled(AbsListView.java:1144) 04-25 01:37:23.280: E/AndroidRuntime(711): at com.sendit.LoaderCursor$ContactsCursorLoaderListFragment.onActivityCreated(LoaderCursor.java:107) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:847) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1032) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.BackStackRecord.run(BackStackRecord.java:622) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1382) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.Activity.performStart(Activity.java:4474) 04-25 01:37:23.280: E/AndroidRuntime(711): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1929) 04-25 01:37:23.280: E/AndroidRuntime(711): ... 11 more 

después de que se llama al método setFastScrollEnabled() , llama al método getSections() del adaptador personalizado, que es donde se bloquea.

 public class LoaderCursor extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FragmentManager fm = getFragmentManager(); // Create the list fragment and add it as our sole content. if (fm.findFragmentById(android.R.id.content) == null) { ContactsCursorLoaderListFragment list = new ContactsCursorLoaderListFragment(); fm.beginTransaction().add(android.R.id.content, list).commit(); } } public static class ContactsCursorLoaderListFragment extends ListFragment implements LoaderManager.LoaderCallbacks { ContactsCursorAdapter mAdapter; Cursor mCursor; String mCurFilter; @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); populateContactList(); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this); ListView lv = getListView(); lv.setFastScrollEnabled(true); //lv.setScrollingCacheEnabled(true); lv.setDivider(getResources().getDrawable(R.drawable.list_divider)); } // These are the Contacts rows that we will retrieve. final String[] CONTACTS_SUMMARY_PROJECTION = new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, ContactsContract.Contacts.PHOTO_ID, }; public Loader onCreateLoader(int id, Bundle args) { // This is called when a new Loader needs to be created. This // sample only has one Loader, so we don't care about the ID. // First, pick the base URI to use depending on whether we are // currently filtering. Uri baseUri; if (mCurFilter != null) { baseUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_FILTER_URI,Uri.encode(mCurFilter)); } else { baseUri = ContactsContract.Contacts.CONTENT_URI; } // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. String selection = "((" + ContactsContract.Contacts.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.Contacts.HAS_PHONE_NUMBER + "=1) AND (" + ContactsContract.Contacts.DISPLAY_NAME + " != '' ))"; String sortOrder = ContactsContract.Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC"; return new CursorLoader(getActivity(), baseUri, CONTACTS_SUMMARY_PROJECTION, selection, null, sortOrder); } public void onLoadFinished(Loader loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); } public void onLoaderReset(Loader loader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. mAdapter.swapCursor(null); } /** * Populate the contact list */ private void populateContactList() { // start mappings String[] from = new String[] { ContactsContract.Contacts.DISPLAY_NAME }; int[] to = new int[] { R.id.contactInfo }; // Create an empty adapter we will use to display the loaded data. mAdapter = new ContactsCursorAdapter(getActivity().getApplicationContext(), R.layout.contact_manager, null, from, to); setListAdapter(mAdapter); } } } 

Y si comento la llamada a setFastScrollEnabled() , entonces no se produce un error, pero no veo que AlphabetIndexer funcione.

¿Es necesario implementar esto de manera diferente porque mi adaptador personalizado está configurado en un ListFragment y no en ListActivity ?

¿Alguien tiene sugerencias sobre cómo hacer que todo esto funcione?

Así que finalmente conseguí que esto funcionara. Así es como lo hice:

Yo añadí:

 ListView lv = getListView(); lv.setFastScrollEnabled(true); lv.setScrollingCacheEnabled(true); 

al método onLoadFinished() después de que el nuevo cursor se intercambió como así

 public void onLoadFinished(Loader loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) mAdapter.swapCursor(data); ListView lv = getListView(); lv.setFastScrollEnabled(true); lv.setScrollingCacheEnabled(true); } 

en consecuencia, estas tres declaraciones fueron eliminadas del método onActivityCreated() de mi ListFragment personalizado.

    Intereting Posts