gpt4 book ai didi

android - 带有由 LoaderManager 管理的自定义适配器的 AlphabetIndexer

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:07:47 25 4
gpt4 key购买 nike

我正在尝试用这样的自定义适配器实现 AlphabetIndexer

AlphabetIndexer with Custom Adapter

我的类 ContactsCursorAdapter 扩展了 SimpleCursorAdapter 并实现了 SectionIndexer我正在使用 LoaderManager 来管理我的适配器的光标,所以我已经覆盖了 swapCursor() 方法,就像上面示例的第二个答案所示。

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

但是,如果我将 ListView 设置为 fastScrollEnabled = true,则会出错

getListView().setFastScrollEnabled(true);

在我的类 ContactsCursorLoaderListFragment 中,它扩展了 ListFragment 并实现了 LoaderManager.LoaderCallbacks。

这是堆栈跟踪:

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

setFastScrollEnabled() 方法被调用后,它会调用自定义适配器的 getSections() 方法,这是它崩溃的地方。

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

}
}

如果我评论 setFastScrollEnabled() 调用,那么它不会出错,但我没有看到 AlphabetIndexer 工作。

这是否需要以不同方式实现,因为我的自定义适配器设置在 ListFragment 而不是 ListActivity 中?

有没有人对如何使这一切正常工作有建议?

最佳答案

所以我终于让它工作了。这是我的做法:

我补充说:

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

像这样换入新光标后到 onLoadFinished() 方法

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

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

}

因此,这三个语句已从我的自定义 ListFragmentonActivityCreated() 方法中删除。

关于android - 带有由 LoaderManager 管理的自定义适配器的 AlphabetIndexer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10224233/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com