J'implémente un ListActivity et ListFragment et voudrais permettre à l'utilisateur d'utiliser des robinets courts et longs - être court pour éditer/montrer les détails de l'article et appuyez longuement pour faire apparaître un menu contextuel avec l'option de supprimer l'article. Toutefois, je ne semble pas pouvoir déclencher le onCreateContextMenu. onListItemClick fonctionne très bien et capture tous les taps, courts ou longs. Le ListFragment est rempli à l'aide d'un SimpleCursorAdaptor et d'un LoaderManager légèrement personnalisés, sans utiliser de fichier de mise en page.Android ListFragment: comment avoir à la fois onListItemClick et onContextItemSelected?
Est-il possible d'avoir les deux?
code ...
LocationsListFragment.java
package com.level3.connect.locations;
//import removed for brevity
public class LocationsListFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor>{
private static final int DELETE_ID = Menu.FIRST + 1;
private SimpleCursorAdapter adapter;
private OnLocationSelectedListener locationSelectedListener;
// the activity attaching to this fragment should implement this interface
public interface OnLocationSelectedListener {
public void onLocationSelected(String locationId);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { LocationsTable.LOCATION_NAME,
LocationsTable.LOCATION_PHONE_NAME };
// Fields on the UI to which we map
int[] to = new int[] { R.id.titleText, R.id.phoneText };
// connect to the database
getLoaderManager().initLoader(0, null, this);
adapter = new LocationCursorAdapter(getActivity(),
R.layout.location_row, null, from, to, 0);
setListAdapter(adapter);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = super.onCreateView(inflater, container, savedInstanceState);
registerForContextMenu(root); //this is called fine
return root;
}
// hook up listening for the user selecting a location in the list
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
locationSelectedListener = (OnLocationSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnLocationSelectedListener");
}
}
// handle user tapping a location - show a detailed view - this works fine
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
String projection[] = { LocationsTable.KEY_ID };
Cursor locationCursor = getActivity().getContentResolver().query(
Uri.withAppendedPath(DatabaseContentProvider.CONTENT_URI,
String.valueOf(id)), projection, null, null, null);
if (locationCursor.moveToFirst()) {
String locationUrl = locationCursor.getString(0);
locationSelectedListener.onLocationSelected(locationUrl);
}
locationCursor.close();
}
// Context menu - this is never called
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
}
@Override - this is never called
public boolean onContextItemSelected(android.view.MenuItem item) {
switch (item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
Uri uri = Uri.parse(DatabaseContentProvider.CONTENT_URI + "/"
+ info.id);
getActivity().getContentResolver().delete(uri, null, null);
return true;
}
return super.onContextItemSelected(item);
}
// Loader code
// Creates a new loader after the initLoader() call
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { LocationsTable.KEY_ID, LocationsTable.LOCATION_NAME, LocationsTable.LOCATION_PHONE_NAME };
CursorLoader cursorLoader = new CursorLoader(getActivity(),
DatabaseContentProvider.CONTENT_URI, projection, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}
}
MISE À JOUR: J'ai toujours pas compris cela et je me demande si je dois renoncer à cette stratégie et la mettre en œuvre dans un autre, et non de manière conviviale. Peut-être un coup d'oeil pour voir les détails et un robinet pour supprimer?