Reputation: 3111
Can anyone point me to a simple example of using a CursorLoader to query a SQLite database and populate a ListFragment? The code below will compile, but when I run it, LogCat tells me that "ListFrag" cannot be cast LoaderManager.LoaderCallbacks. If I change ListFrag so that it's not ListFrag, just ListFrag, I'm told that "ListFrag cannot be cast to android.v4.support.Fragment". Note that my activity extends FragmentActivity and my Fragment extends ListFragment because of the information in this forum post. I've been struggling with getting this to work for a while now and I just don't get it. Here's my code for the activity which contains the fragment and thank you:
import android.os.Bundle;
import android.support.v4.app.FragmentActivity
public class MyList extends FragmentActivity {
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.myfragment);
}
}
And here's my code for the fragment:
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;
import android.support.v4.widget.SimpleCursorAdapter;
import android.support.v4.app.LoaderManager;
import android.view.View;
import android.widget.ListView;
@SuppressWarnings("hiding")
public class ListFrag<Cursor> extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TABLE_BASEPATH = "MyTable_tbl";
private static final String AUTHORITY = "SQLData";
public static final Uri MY_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_BASEPATH);
private static final String[] PROJECTION = new String[] { "_id", "fieldname" };
private SimpleCursorAdapter mAdapter;
private static final int LOADER_ID = 0;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@SuppressWarnings("unchecked")
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Intent myData = getActivity().getIntent();
Bundle info = myData.getExtras();
SimpleCursorAdapter adapter;
String[] dataColumns = { "fieldname" };
int[] viewIDs = { R.id.mydetails };
adapter = new SimpleCursorAdapter(getActivity(), R.layout.mylist, null, dataColumns, viewIDs, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(adapter);
getLoaderManager().initLoader(0, info, (LoaderCallbacks<Cursor>) this);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String item = (String) getListAdapter().getItem(position);
DetailFrag frag = (DetailFrag) getFragmentManager().findFragmentById(R.id.frag_detail);
if (frag != null && frag.isInLayout()) {
frag.setText(item);
}
}
@SuppressWarnings("unchecked")
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String selection = "level='" + args.getString("Level") + "'";
return (Loader<Cursor>) new CursorLoader(getActivity(), MY_URI,
PROJECTION, selection, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
switch (loader.getId()) {
case LOADER_ID:
mAdapter.swapCursor((android.database.Cursor) cursor);
break;
}
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
Just saw your comment about LogCat. Oops. Here's my entire LogCat:
11-05 15:47:27.953: D/dalvikvm(553): Not late-enabling CheckJNI (already on)
11-05 15:47:28.643: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:28.683: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
11-05 15:47:29.143: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:29.153: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
11-05 15:47:29.643: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:29.653: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
11-05 15:47:30.143: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:30.153: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
11-05 15:47:30.643: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:30.693: D/gralloc_goldfish(553): Emulator without GPU emulation detected.
11-05 15:47:30.693: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
11-05 15:47:32.843: E/ActivityThread(553): Failed to find provider info for SQLData
11-05 15:47:32.883: D/AndroidRuntime(553): Shutting down VM
11-05 15:47:32.883: W/dalvikvm(553): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
11-05 15:47:32.903: E/AndroidRuntime(553): FATAL EXCEPTION: main
11-05 15:47:32.903: E/AndroidRuntime(553): java.lang.NullPointerException
11-05 15:47:32.903: E/AndroidRuntime(553): at com.MyKnitCards.project.ListFrag.onLoadFinished(ListFrag.java:71)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.callOnLoadFinished(LoaderManager.java:425)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.app.LoaderManagerImpl$LoaderInfo.onLoadComplete(LoaderManager.java:393)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.Loader.deliverResult(Loader.java:103)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:81)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.CursorLoader.deliverResult(CursorLoader.java:35)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.AsyncTaskLoader.dispatchOnLoadComplete(AsyncTaskLoader.java:221)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.AsyncTaskLoader$LoadTask.onPostExecute(AsyncTaskLoader.java:61)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.ModernAsyncTask.finish(ModernAsyncTask.java:461)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.ModernAsyncTask.access$500(ModernAsyncTask.java:47)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.support.v4.content.ModernAsyncTask$InternalHandler.handleMessage(ModernAsyncTask.java:474)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.os.Looper.loop(Looper.java:137)
11-05 15:47:32.903: E/AndroidRuntime(553): at android.app.ActivityThread.main(ActivityThread.java:4424)
11-05 15:47:32.903: E/AndroidRuntime(553): at java.lang.reflect.Method.invokeNative(Native Method)
11-05 15:47:32.903: E/AndroidRuntime(553): at java.lang.reflect.Method.invoke(Method.java:511)
11-05 15:47:32.903: E/AndroidRuntime(553): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-05 15:47:32.903: E/AndroidRuntime(553): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-05 15:47:32.903: E/AndroidRuntime(553): at dalvik.system.NativeStart.main(Native Method)
11-05 15:47:33.213: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:33.233: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
11-05 15:47:33.513: I/dalvikvm(553): threadid=3: reacting to signal 3
11-05 15:47:33.533: I/dalvikvm(553): Wrote stack traces to '/data/anr/traces.txt'
Upvotes: 1
Views: 5115
Reputation: 169
You should check Sherlock, they offer different versions of loaders working with fragments. You just have to download their package and inside you can find the samples working.
Ups, I just saw this is seven months old. Hope it is still usefull.
Upvotes: 0
Reputation: 86948
First try switching these imports to the support library versions. Change:
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
to:
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
Next make sure you are asking for the support fragment manager:
DetailFrag frag = (DetailFrag) getActivity().getSupportFragmentManager().findFragmentById(R.id.frag_detail);
// ^^^^^^^
(This might not solve everything, if you still need help post the LogCat errors from these changes so we can see exactly what is happening.)
Addition
mAdapter
is null
, change adapter
to mAdapter
here:
mAdapter = new SimpleCursorAdapter(getActivity(), R.layout.mylist, null, dataColumns, viewIDs, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
Upvotes: 3