AlphabetIndexer mit benutzerdefiniertem Adapter, der von LoaderManager verwaltet wird

Ich versuche umzusetzenAlphabetIndexer mit Custom Adapter wie folgt

AlphabetIndexer mit benutzerdefiniertem Adapter

Meine Klasse ContactsCursorAdapter wird erweitertSimpleCursorAdapter und implementiertSectionIndexer und ich benutze eineLoaderManager um den Cursor meines Adapters zu verwalten, habe ich denswapCursor() Methode wie die zweite Antwort auf das obige Beispiel zeigt.

<code>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);
    }
}
</code>

Dieser Fehler tritt jedoch auf, wenn ich meine Listenansicht auf fastScrollEnabled = true setze

getListView (). setFastScrollEnabled (true);

in meiner Klasse ContactsCursorLoaderListFragment, die erweitert wirdListFragment und implementiert LoaderManager.LoaderCallbacks.

Hier ist der Stack-Trace:

<code>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.<init>(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
</code>

nach demsetFastScrollEnabled() Methode wird aufgerufen, ruft den benutzerdefinierten Adapter aufgetSections() Methode, bei der es abstürzt.

<code>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<Cursor> {

        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<Cursor> 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<Cursor> 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<Cursor> 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);
        }   

    }
}
</code>

Und wenn ich das kommentieresetFastScrollEnabled() anrufen, dann irrt es nicht aus, aber ich sehe das nichtAlphabetIndexer Arbeiten.

Muss dies anders implementiert werden, da mein benutzerdefinierter Adapter in a festgelegt ist?ListFragment und nicht aListActivity?

Hat jemand Vorschläge, wie das alles funktioniert?

Antworten auf die Frage(1)

Ihre Antwort auf die Frage