I have a ListView displaying custom views (3 TextViews per item); I have just implemented a context menu like such:
// in onCreateView
ListView list = (ListView) view.findViewById(R.id.list);
registerForContextMenu(list);
and
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
if (v.getId() == R.id.list) {
MenuInflater inflater = getActivity().getMenuInflater();
inflater.inflate(R.menu.todo_context_menu, menu);
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.edit:
// your first action code
return true;
case R.id.delete:
// your second action code
return true;
default:
return super.onContextItemSelected(item);
}
}
I wish to know which item has been long clicked (its position in the ListView would be ideal) in order to edit or delete the right one.
How may that be achieved?
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int index = info.position;
switch (item.getItemId()) {
case R.id.edit:
// your first action code
return true;
case R.id.delete:
// your second action code
return true;
default:
return super.onContextItemSelected(item);
}
}
Related
So, I know we need to pass a view to openContextMenu(view); but where can i get the view for Menuitem, please have a look at my code. Thanks in advance.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_activity_actions, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.actionmenu:
openContextMenu(item); //I dont know what to pass here
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Select The Action");
menu.add(0, 0, 11, "Edit");
menu.add(0, 1, 12, "Delete");
}
#Override
public boolean onContextItemSelected(MenuItem item) {
System.out.println(item.getItemId());
return super.onContextItemSelected(item);
}
1. Register a view for a floating context menu
By default, a long-press on a view does not trigger the creation of a context menu.
You must register a view for a floating context menu by calling the following method,
a listview for example:
ListView listView = (ListView) v.findViewById(android.R.id.list);
registerForContextMenu(listView);
2. Create resource xml file
You'd better to create a xml resource file that contains the context menu item:
your_context.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="#+id/context_menu_eidt"
android:title="Edit" />
<item android:id="#+id/context_menu_delete"
android:title="Delete" />
</menu>
3. Inflate the resouce to build context menu
Then inflate the resource file in onCreateContextMenu method,
the parameter #v is the view that the context menu is being built for:
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
if (v.getId() == android.R.id.list) {
Log.d(TAG, "get the view here");
}
getActivity().getMenuInflater().inflate(R.menu.your_context, menu);
}
4. Do something when menu item selected
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
int position = info.position;
switch (item.getItemId()) {
case R.id.context_menu_eidt:
// TODO
return true;
case R.id.context_menu_delete:
// TODO
return true;
}
return super.onContextItemSelected(item);
}
That's all.
Already had the ability to delete a listview item using an onItemLongClick method but I'd rather use a floating context menu to do this.
Below is the code I currently have for the floating context menu. I followed the documentation which helped me set it up and then tried to search for a similar example to what I'm doing but couldn't find anything appropriate.
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.payments_context, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
return true;
case R.id.delete:
return true;
default:
return super.onContextItemSelected(item);
}
}
This is the code I had to delete the items in my listview before I decided to switch to a floating context menu
public boolean onItemLongClick (AdapterView<?> parent, View view, int position, long id)
{
String temp = paymentTitle.get(position).toString();
paymentTitle.remove(position);
paymentDate.remove(position);
reminderDate.remove(position);
reminderTime.remove(position);
paymentVal.remove(position);
mDatabase = new MOSDatabase(this);
SQLiteDatabase readableDB = mDatabase.getWritableDatabase();
readableDB.delete("PaymentTable", "PTITLE=?",
new String[]{temp});
aa.notifyDataSetChanged();
return false;
}
If someone could advise me on how to get this floating context menu working I'd be really grateful. I don't have the edit method done just yet, it's what I have to do after I get this completed.
If I understand correctly, you can get the index of the item in the ListView at the click position by using the following code:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
int position = info.position;
Using position, you can reuse the code of onItemLongClick pretty much as is:
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
int position = info.position;
switch (item.getItemId()) {
case R.id.edit:
return true;
case R.id.delete: {
String temp = paymentTitle.get(position).toString();
paymentTitle.remove(position);
paymentDate.remove(position);
reminderDate.remove(position);
reminderTime.remove(position);
paymentVal.remove(position);
mDatabase = new MOSDatabase(this);
SQLiteDatabase readableDB = mDatabase.getWritableDatabase();
readableDB.delete("PaymentTable", "PTITLE=?",
new String[]{temp});
aa.notifyDataSetChanged();
}
return true;
default:
return super.onContextItemSelected(item);
}
}
You might want to look at the answer to this question.
What's the difference between ContextMenuInfo.id and item.getItemId in the callback onContextItemSelected()?
How can I display a ContextMenu in my AVD? Thank you!!
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.edit:
editNote(info.id);
return true;
case R.id.delete:
deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
Inflate the menu before passing it into super.onCreateContextMenu.
ContextMenuInfo is the extra data that the view that initiated the context menu can setup - so there are edit and delete buttons with different item.getItemId(), but info.id gives the view that was used to create the menu (the item to be edited).
My app contains 1 list view, data source is 1 sqlite table, when i hold long click on any row in listview it will show me 1 menu option to change the color of that row, for this i have used onContextItemSelected function, on selecting menu option it will call 1 function change_color. What should i write in change_color function so that i can change row bg color.
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, PROCESSED_ID, 0, R.string.menu_processed);
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case PROCESSED_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
change_color();
return true;
}
return super.onContextItemSelected(item);
}
Call your method as :
change_color(pass_your_list_view, pass_selected_position_of_list_view);
And define change_color() as:
private void change_color(ListView listView, int position) {
listView.getChildAt(position).setBackgroundColor(Color.BLACK);
}
Hope this will help.
Edited
Define a variable a position
public static int position;
And replace your code as
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.add(0, PROCESSED_ID, 0, R.string.menu_processed);
// Get the info on which item was selected
AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
// Retrieve the position at where you long pressed
position = info.position;
}
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case PROCESSED_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
change_color(getListView(), position);
return true;
}
return super.onContextItemSelected(item);
}
refer to this tutorial Colored Row in List View
How does one register a ListView for a context menu when using a custom ListView based on BaseAdapter?
I tried registerForContextMenu(getListView());, but this doesn't seem to work. I'm using ListView14.java from API Demos.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(new EfficientAdapter(this));
registerForContextMenu(getListView());
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.tag_context_menu, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId()) {
case R.id.tagView:
// editNote(info.id);
return true;
case R.id.tagRename:
// deleteNote(info.id);
return true;
case R.id.tagDelete:
// deleteNote(info.id);
return true;
default:
return super.onContextItemSelected(item);
}
}
Instead of using registerForContextMenu(getListView()), try naming your listview in onCreate and using that reference:
Listview myListView = (Listview) findViewById(R.id.myListView); //or use any other constructor
registerForContextMenu(myListView);
This works for all the items in my adapter-fed Gridview (although it's turning out to be impossible to then properly adding a contextmenu to the gridview itself which registers longclicks on the empty gridview items, but that's another story altogether :) ), and I'd imagine a Listview to work the same.