就像标题一样,当{是Loader<Cursor> onCreateLoader(int, Bundle)
被调用与片段生命周期有关时?我正在尝试实现由Content Provider支持的CursorLoader来填充片段内的ListView。创建片段时,列表视图不会填充,但是当我退出活动时(通过启动另一个intent)并返回带有CursorLoader的片段(导致再次查询Content Provider),列表视图将按预期填充。 / p>
这使我怀疑我的初始化和/或查询顺序不正确。在我的Content Provider查询方法中,我调用cursor.setNotificationUri(contentResolver, uri)
并在insert语句中调用getContext().getContentResolver().notifyChange(uri, null)
。
非常感谢任何帮助!
的ContentProvider
public class VenueProvider extends ContentProvider {
public static final String TAG = "VenueProvider";
DatabaseHelper databaseHelper;
public static final String AUTHORITY = "com.androidtitan.hotspots.Provider.VenueProvider";
public static final String BASE_PATH = DatabaseHelper.TABLE_VENUES;
public static String base_CONTENT_URI = "content://" + AUTHORITY
+ "/" + BASE_PATH + "/";
//MIME Types for getting a single item or a list of them
public static final String VENUES_MIME_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
+ "/vnd.com.androidtitan.Data.venues";
public static final String VENUE_MIME_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
+ "/vnd.com.androidtitan.Data.venues";
//Column names
public static class InterfaceConstants {
public static final String id = "_id";
public static final String venue_name = "venue_name";
public static final String venue_city = "venue_city";
public static final String venue_category = "venue_category";
public static final String venue_id_string = "venue_string";
public static final String venue_rating = "venue_rating";
}
//URI matcher variable
private static final int GET_ALL = 0;
private static final int GET_ONE = 1;
private static final int GET_SELECT = 2;
static UriMatcher uriMatcher = BuildUriMatcher();
static UriMatcher BuildUriMatcher() {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
//Uri to match and the code to return when matched
matcher.addURI(AUTHORITY, BASE_PATH, GET_ALL);
matcher.addURI(AUTHORITY, BASE_PATH + "/#", GET_ONE);
matcher.addURI(AUTHORITY, BASE_PATH + "/*", GET_SELECT);
return matcher;
}
@Override
public boolean onCreate() {
databaseHelper = DatabaseHelper.getInstance(getContext());
return true;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
Cursor queryCursor;
switch(uriMatcher.match(uri)) {
case GET_ALL:
queryCursor = databaseHelper.getReadableDatabase().rawQuery("SELECT * FROM "
+ DatabaseHelper.TABLE_VENUES, null);
break;
case GET_ONE:
queryCursor = databaseHelper.getReadableDatabase().rawQuery("SELECT * FROM "
+ DatabaseHelper.TABLE_VENUES
+ " WHERE " + DatabaseHelper.KEY_ID + " = " + uri.getLastPathSegment(), null);
break;
case GET_SELECT:
String selectionQuery = "SELECT * FROM " + DatabaseHelper.TABLE_VENUES + " td, "
+ DatabaseHelper.TABLE_COORDINATES + " tg, " + DatabaseHelper.TABLE_COORDINATES_VENUES
+ " tt WHERE tg." + DatabaseHelper.KEY_LOCAL + " = ? AND tg." + DatabaseHelper.KEY_ID
+ " = " + "tt." + DatabaseHelper.KEY_COORDS_ID + " AND td." + DatabaseHelper.KEY_ID
+ " = " + "tt." + DatabaseHelper.KEY_VENUES_ID;
Log.e(TAG, "selectionQuery: " + selectionQuery);
queryCursor = databaseHelper.getReadableDatabase().rawQuery(selectionQuery,
new String[] { String.valueOf(uri.getLastPathSegment()) });
break;
default:
throw new IllegalArgumentException("Unknown Uri:" + uri);
}
// Tell the cursor what uri to watch, so it knows when its source data changes
queryCursor.setNotificationUri(getContext().getContentResolver(), uri);
return queryCursor;
}
@Override
public String getType(Uri uri) {
switch(uriMatcher.match(uri)) {
case GET_ALL:
return VENUES_MIME_TYPE;
case GET_ONE:
return VENUE_MIME_TYPE;
case GET_SELECT:
return VENUES_MIME_TYPE;
default:
throw new IllegalArgumentException("Unknown uri: " + uri);
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase database = databaseHelper.getWritableDatabase();
long insertId = 0;
switch(uriType) {
case GET_ONE:
insertId = database.insert(DatabaseHelper.TABLE_VENUES, null, values);
break;
case GET_ALL:
break;
case GET_SELECT:
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
Log.e(TAG,"KEY_ID " + uri.getLastPathSegment()
+ " KEY_LOCATION_ID " + values.getAsLong(DatabaseHelper.KEY_VENUE_LOCATION_ID));
databaseHelper.assignVenueToLocation(Long.valueOf(uri.getLastPathSegment()),
values.getAsLong(DatabaseHelper.KEY_VENUE_LOCATION_ID));
getContext().getContentResolver().notifyChange(uri, null);
return uri;
//return Uri.parse(DatabaseHelper.TABLE_VENUES + "/" + insertId);
}
//todo:::
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
int uriType = uriMatcher.match(uri);
SQLiteDatabase database = databaseHelper.getWritableDatabase();
int updateId = 0;
switch(uriType) {
case GET_ONE:
updateId = database.update(DatabaseHelper.TABLE_VENUES, values, null, null);
break;
case GET_ALL:
break;
case GET_SELECT:
break;
default:
throw new IllegalArgumentException("Unknown URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return updateId;
}
}
初始化Loader的片段
public class VenueResultsFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "VenueResultsFragment";
DatabaseHelper databaseHelper;
LocationBundle focusLocation;
// String locationName;
int locationIndex;
private static final String[] PROJECTION = new String[]{
VenueProvider.InterfaceConstants.id,
VenueProvider.InterfaceConstants.venue_name,
VenueProvider.InterfaceConstants.venue_city,
VenueProvider.InterfaceConstants.venue_category,
VenueProvider.InterfaceConstants.venue_id_string,
VenueProvider.InterfaceConstants.venue_rating};
private static final int LOADER_ID = 1;
private LoaderManager.LoaderCallbacks<Cursor> callBacks;
private SimpleCursorAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
databaseHelper = DatabaseHelper.getInstance(getActivity());
locationIndex = getArguments().getInt(MapsActivity.venueFragmentLocIndex);
focusLocation = databaseHelper.getAllLocations().get(locationIndex);
if (databaseHelper.getAllVenuesFromLocation(focusLocation).size() == 0) {
new FoursquareHandler(getActivity(), focusLocation.getLatlng().latitude,
focusLocation.getLatlng().longitude, locationIndex);
}
String[] dataColumns = {VenueProvider.InterfaceConstants.venue_name};
int[] viewItems = {R.id.nameTextView};
adapter = new SimpleCursorAdapter(getActivity(), R.layout.listview_venue_item, null,
dataColumns, viewItems, 0);
setListAdapter(adapter);
callBacks = this;
LoaderManager lm = getLoaderManager();
lm.initLoader(LOADER_ID, null, callBacks);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_venue_results, container, false);
return v;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
//mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement Interface");
}
}
@Override
public void onDetach() {
super.onDetach();
//mListener = null;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
Log.e(TAG, "pre-cursorLoader locationName: " + focusLocation.getLocalName());
return new CursorLoader(getActivity(), Uri.parse(VenueProvider.base_CONTENT_URI + focusLocation.getLocalName()),
PROJECTION, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
// switch (loader.getId()) {
//case LOADER_ID:
// break;
// }
adapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
答案 0 :(得分:0)
所以事实证明我遇到的问题是我查询不好。事情很好,我修好了。
我阅读了这篇文章,它为我做了直截了当的事:How does CursorLoader with LoaderManager know to send the cursor to a CursorAdapter?
要回答我的问题,尽管在调用内容提供程序时会创建内容提供程序,这将是scanAreaView!.bounds
。 getLoaderManager.initLoader()
然后填充Loader,然后Loader将信息传递给适配器。
如果我错了,有人可以纠正我或添加一些东西吗?