I have a dialog that shows a list of items, I need to be able to edit/delete items in this list so I put a context menu in so when the user long presses on an item it they can choose what they want to do (edit or delete the item).
The problem is that onContextItemSelected never gets called when an item in the context menu is selected.
I checked to see if maybe the activity that created the dialog fragment is getting the callback but that is not either so why is there it not getting called? Can you not do a context menu in a dialog?
public class TypesDialogList extends DialogFragment implements LoaderManager.LoaderCallbacks<Cursor>,OnItemClickListener,OnCreateContextMenuListener{
ListView lv;
SimpleCursorAdapter mAdapter;
private int EDIT_TYPE = 1;
private int DELETE_TYPE = 2;
OnEditType mType;
public Dialog onCreateDialog(Bundle state){
final View v = getActivity().getLayoutInflater().inflate(R.layout.layer_dialog_layout, null, false);
lv = (ListView)v.findViewById(R.id.listView1);
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setOnItemClickListener(this);
lv.setOnCreateContextMenuListener(this);
return new AlertDialog.Builder(getActivity()).setView(v).setPositiveButton("Add Type", new OnClickListener(){
public void onClick(DialogInterface dialog, int which) {
}
}).setTitle("Type's").create();
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo){
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
long id = info.id;
if(id > 3){
menu.setHeaderTitle("Type Menu");
menu.add(Menu.NONE, EDIT_TYPE, 1, "Edit");
menu.add(Menu.NONE, DELETE_TYPE, 2, "Delete");
}else{
Toast.makeText(getActivity(),"Cannot edit type",Toast.LENGTH_SHORT).show();
}
}
#Override
public boolean onContextItemSelected(MenuItem item) {
super.onContextItemSelected(item);
AdapterView.AdapterContextMenuInfo oMenuInfo = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
long id = oMenuInfo.id;
if(item.getItemId() == EDIT_TYPE){
}else if(item.getItemId() == DELETE_TYPE){
}
return true;
}
}
For anybody still looking for a workaround, I just solved this problem by creating an anonymous OnMenuItemClickListener that delegates back to onContextItemSelected(MenuItem item) and setting it on all the items in my menu.
#Override
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
// Creation/inflate menu here
OnMenuItemClickListener listener = new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
onContextItemSelected(item);
return true;
}
};
for (int i = 0, n = menu.size(); i < n; i++)
menu.getItem(i).setOnMenuItemClickListener(listener);
}
Related
How to delete item from ListView using onCreateContextMenu? There is some problem in the code below. Any solution?
When item in listview is long pressed a menu popups in which there is an option of delete.
public class ContextMenuTest extends AppCompatActivity {
ListView listView;
String []name={"ANKUSH", "ANOUSHKA", "SHIVA", "SOMANSHU"};
String current;
ArrayAdapter<String> adapter;
int pos;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_context_menu_test);
listView = (ListView) findViewById(R.id.lvContextMenu);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, name);
listView.setAdapter(adapter);
registerForContextMenu(listView);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("SELECT OPTION");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_test, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId())
{
case R.id.delete:
adapter.remove(adapter.getItem(info.position));
break;
}
return true;
}
}
In the onContextItemSelected method, add adapter.notifyDataSetChanged() to notify the adapter of changes to the data.
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId())
{
case R.id.delete:
adapter.remove(adapter.getItem(info.position));
adapter.notifyDataSetChanged();
break;
}
return true;
}
This Works
public class ContextMenuTest extends AppCompatActivity {
ListView listView;
List<String> list = new ArrayList<String>();
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_context_menu_test);
listView = (ListView) findViewById(R.id.lvContextMenu);
list.add("ANKUSH");
list.add("ANOUSHKA");
list.add("SHIVA");
list.add("SOMANSHU");
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, list);
listView.setAdapter(adapter);
registerForContextMenu(listView);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("SELECT OPTION");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_test, menu);
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch (item.getItemId())
{
case R.id.delete:
list.remove(info.position);
adapter.notifyDataSetChanged();
return true;
default:
return super.onContextItemSelected(item);
}
}
}
I have a listview with a custon adapter. I have to put a context menu for it, but it's not working. And I put the onItemLongClick to the list and it's not working too. I don't know how to trigger the contextmenu. If I have to click on an item or long click on it. I do register a long click to get the id from the item.
EDIT I think i figure out whats the problem. I have a button on my item listview. I remove this button from the layout and the context menu worked fine. But I need this button. Why the button was causing problem in the context menu?
This is the class:
public class HistoricoDespesasActivity extends Activity {
Helper h;
AlphaAnimation buttonClick;
DespesasDAO dDAO;
ListView lv;
DespesaHistoricoAdapter adapter;
int idDespesasSelecionada;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_historico_despesas);
lv = (ListView)findViewById(R.id.lvHistoricoDespesas);
TextView tvMarcaModelo = (TextView)findViewById(R.id.tvMarcaModeloCabecalho);
TextView tvApelido = (TextView)findViewById(R.id.tvApelidoCabecalho);
tvApelido.setVisibility(View.INVISIBLE);
tvMarcaModelo.setVisibility(View.INVISIBLE);
buttonClick = new AlphaAnimation(1, 0.5f);
h = new Helper(this);
h.mostraVeiculoAtivo();
adapter = new DespesaHistoricoAdapter(this);
dDAO = new DespesasDAO(this);
dDAO.open();
Cursor cursor = dDAO.consultarTodasDespesasByIdVeiculo(h.getId());
int id;
String data;
String tipoDespesa = null;
double valor;
int tipo = 0;
if(cursor != null && cursor.moveToFirst()){
do {
id = cursor.getInt(cursor.getColumnIndex(DespesasDAO.COLUNA_ID));
data = cursor.getString(cursor.getColumnIndex(DespesasDAO.COLUNA_DESPESA_DATA));
tipo = cursor.getInt(cursor.getColumnIndex(DespesasDAO.COLUNA_ITEM_ID));
valor = cursor.getDouble(cursor.getColumnIndex(DespesasDAO.COLUNA_DESPESA_VALOR));
if(tipo == 1){
tipoDespesa = "Pedágio";
} else if(tipo == 2){
tipoDespesa = "Estacionamento";
} else if(tipo == 3){
tipoDespesa = "Lavagem";
} else if(tipo == 4){
tipoDespesa = "Diversos";
}
adapter.addDespesa(id, tipoDespesa, data, valor);
} while (cursor.moveToNext());
cursor.close();
dDAO.close();
lv.setAdapter(adapter);
}
lv.setLongClickable(true);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
idDespesasSelecionada = (Integer) parent.getItemAtPosition(position);
return true;
}
});
registerForContextMenu(lv);
}
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
menu.setHeaderTitle("Despesas");
menu.add(0, v.getId(), 0, "Deletar");
}
#Override
public boolean onContextItemSelected(MenuItem item) {
if(item.getTitle().equals("Deletar")){
dDAO.open();
dDAO.removerDespesasById(idDespesasSelecionada);
dDAO.close();
}
onCreate(new Bundle());
return super.onContextItemSelected(item);
}
#Override
protected void onResume() {
onCreate(new Bundle());
super.onResume();
}
}
Remove your setOnItemLongClickListener of listView and replace onContextItemSelected with this
#Override
public boolean onContextItemSelected(MenuItem item)
{
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
if(item.getTitle().equals("Deletar"))
{
dDAO.open();
dDAO.removerDespesasById(info.position);
dDAO.close();
}
return true;
}
change onCreateContextMenu like this :
#Override
public void onCreateContextMenu(ContextMenu menu, View v,ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater =getMenuInflater();
inflater.inflate(R.menu.more_tab_menu, menu);
}
see this topic :
Android, How to create Context Menu...
EDIT :
use button. image Button and list view is clickable. if you use Button and set android:focusable="false" android:focusableInTouchMode="false" work fine.
I have created a context menu. The context menu appears, when I do a longclick on the listitems. So far so good...
But when i click on a contextitem, nothing happens. Does anyone know this issue?
What's the problem here?
Button for opening the dialog with listview:
Button cmd_fav = (Button) findViewById(R.id.cmd_main_fav);
cmd_fav.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
List<String> valueList = new ArrayList<String>();
db = SQLiteDatabase.openDatabase("/data/data/spicysoftware.abugrundwissen/databases/questions", null,
SQLiteDatabase.OPEN_READWRITE);
Cursor c_ = db.rawQuery("SELECT question, _id, answer FROM tbl_questions"+
" where favourite = 1", null);
if (c_ != null ) {
if (c_.moveToFirst()) {
do {
String str_question = c_.getString(c_.getColumnIndex("question"));
valueList.add(str_question);
} while (c_.moveToNext());
}
// custom dialog
dialog = new Dialog(MainSite.this);
dialog.setContentView(R.layout.dialog_list);
dialog.setTitle("Favoriten:");
adapter = new ArrayAdapter<String>(MainSite.this, android.R.layout.simple_list_item_1, valueList);
final ListView lv = (ListView)dialog.findViewById(R.id.list_search);
lv.setAdapter(adapter);
registerForContextMenu(lv);
lv.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, CONTEXT_MENU_DELETE_ITEM, Menu.NONE, "Favorit entfernen");
menu.add(Menu.NONE, CONTEXT_MENU_FINISH_ITEM, Menu.NONE, "Frage abschliessen!");
}
});
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
String item = (String) lv.getItemAtPosition(position).toString();
Cursor c_2 = db.rawQuery("SELECT answer FROM tbl_questions"+
" where question = '"+item+"'", null);
if (c_2 != null ) {
if (c_2.moveToFirst()) {
answer = c_2.getString(c_2.getColumnIndex("answer"));
}
}
// custom dialog
final Dialog dialog = new Dialog(MainSite.this);
dialog.setContentView(R.layout.dialog_answer);
dialog.setTitle("Antwort:");
// set the custom dialog components - text, image and button
TextView text = (TextView) dialog.findViewById(R.id.txt_answer);
//text.setText(answer);
text.setText(Html.fromHtml(answer), TextView.BufferType.SPANNABLE);
Button dialogButton = (Button) dialog.findViewById(R.id.cmd_close_dialog);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
});
Button dialogButton = (Button) dialog.findViewById(R.id.cmd_close_dialog2);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.show();
}
}
});
OnContextItemSelected:
#Override
public boolean onContextItemSelected(MenuItem item) {
Log.v("tst", "lol");
switch (item.getItemId()) {
case CONTEXT_MENU_DELETE_ITEM:
Log.v("DELETED", "TRUE");
return true;
case CONTEXT_MENU_FINISH_ITEM:
Log.v("FINISHED", "TRUE");
return true;
}
Log.v("FINISHED", "LOL");
return false;
}
Best Regards
MSeiz5
I found a solution here Android: ContextMenu and ItemSelected in Context Menu
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
//MenuInflater inflater = getMenuInflater();
//inflater.inflate(R.menu.context_menu, menu);
MenuItem delete = menu.add("delete");
MenuItem add = menu.add("add");
add.setIcon(android.R.drawable.ic_menu_upload); //adding icons
delete.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Log.d("ContextCheck","EDIT!");
Toast.makeText(Pr.this, "Edit!", Toast.LENGTH_SHORT).show();
return true;
}
});
add.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Log.d("ContextCheck","EDIT!");
Toast.makeText(Pr.this, "Edit!", Toast.LENGTH_SHORT).show();
return true;
}
});
}
Is Working!
If MenuInflater used, more generic code:
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.ruleitem_menu, menu);
if (menuInfo instanceof AdapterView.AdapterContextMenuInfo){
AdapterView.AdapterContextMenuInfo adptrCmi = (AdapterContextMenuInfo) menuInfo;
String lsItem = currentRuleListView.getItemAtPosition(adptrCmi.position).toString();
menu.setHeaderTitle( lsItem);
}
//if Activity.onContextItemSelected not triggered, try the following lines
for (int i=0; i< menu.size();i++){
menu.getItem(i).setOnMenuItemClickListener(new OnMenuItemClickListener(){
#Override
public boolean onMenuItemClick(MenuItem item) {
return onContextItemSelected(item);
}
});
}
I am using the following method to add a ContextMenu to a custom view i have built but i want to know how to react to the press of that contextmenu.
This is not an Activity so i cannot do this:
#override
public boolean onOptionsItemSelected(MenuItem item) {
Here is the code
private View.OnCreateContextMenuListener vC = new View.OnCreateContextMenuListener() {
#Override
public void onCreateContextMenu(ContextMenu arg0, View arg1,
ContextMenuInfo arg2) {
// TODO Auto-generated method stub
arg0.add(0, 0, 0, "Call");
arg0.add(0, 1, 0, "Map");
arg0.add(0, 2, 0, "Market");
}
};
Update:
Here is a very simplified verion of my class.
public final class NewView extends View {
public NewView(Context context, AttributeSet attrs) {
super(context, attrs);
cntxt = context;
this.setLongClickable(true);
this.setOnLongClickListener(vLong);
this.setOnCreateContextMenuListener(vC);
}
private View.OnLongClickListener vLong = new View.OnLongClickListener() {
public boolean onLongClick(View view) {
showContextMenu();
return true;
}
};
private View.OnCreateContextMenuListener vC = new View.OnCreateContextMenuListener() {
#Override
public void onCreateContextMenu(ContextMenu arg0, View arg1,
ContextMenuInfo arg2) {
// TODO Auto-generated method stub
arg0.add(0, 0, 0, "Call");
arg0.add(0, 1, 0, "Map");
arg0.add(0, 2, 0, "Market");
}
};
}
Noone seem to answer exhaustively TS' question (and mine eventually), thus let me post a solution to this. Given the code above you can attach custom MenuItem's click handlers:
private View.OnCreateContextMenuListener vC = new View.OnCreateContextMenuListener() {
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
menu.add(0, 0, 0, "Call")
.setOnMenuItemClickListener(mMenuItemClickListener);
menu.add(0, 1, 0, "Map")
.setOnMenuItemClickListener(mMenuItemClickListener);
menu.add(0, 2, 0, "Market")
.setOnMenuItemClickListener(mMenuItemClickListener);
}
};
private OnMenuItemClickListener mMenuItemClickListener = new OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case 0:
// do "Call"
return true;
case 1:
// do "Map"
return true;
case 2:
// do "Market"
return true;
}
return false;
}
};
};
Use item.getItemId() and create switch and cases based on the number returned by getItemId()
Something like this.
#override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId())
{
case 1:
Log.i("FIRST ITEM: ", "CALL");
break;
case 2:
Log.i("2nd ITEM: ", "MAP");
break;
case 3:
Log.i("3rd ITEM: ", "Market");
break;
default:
}
}
I hope this is what you meant by reacting on menu items selection. :)
This does seem to be an odd inconsistency in Android - a View can create a context menu, but the handling of said menu can only happen in completely different code?
I'm also solving this with setOnMenuItemClickListener(). The documentation suggests this is reasonable, but it requires effort to set it up if you are using a MenuInflater.
public void onCreateContextMenu(final ContextMenu menu, final View v,
final ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
final MenuInflater menuInflater = this.menuInflater;
menuInflater.inflate(R.menu.context_date, menu);
final int length = menu.size();
for (int index = 0; index < length; index++) {
final MenuItem menuItem = menu.getItem(index);
menuItem.setOnMenuItemClickListener(this);
}
}
You could assign a variable to your View from your activity after you inflate the main layout (in `onCreate).
myView = (View) findViewById(R.id.my_view);
Next, do registerForContextMenu(myView);
Finally, you can override onCreateContextMenu where you can add what happens when the context menu appears.
In the view :
Let your view implements ContextMenuInfo
public class MyView extends View implements ContextMenuInfo
Then, override getContextMenuInfo to return your view.
#Override
protected ContextMenuInfo getContextMenuInfo() {
return this ;
}
In you activity :
Register your view for ContextMenu.
registerForContextMenu(myView);
Then access the view in your activity onContextItemSelected.
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
...
case R.id.action_ctx_wordview_read_tts:
MyView myView = (MyView) item.getMenuInfo();
...
}
}
Note :
When I add an onClickListener to the MyView, the contextMenu stoped working. I had to add the following code to solve the problem.
tvWord.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
return false;
}
});
I have a list view filled with data. I set up a context menu for the listview using the following code:
list.setOnCreateContextMenuListener
(
new View.OnCreateContextMenuListener()
{
public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo)
{
AdapterContextMenuInfo mi =(AdapterContextMenuInfo) menuInfo;
menu.add(0, 0, 0, "Delete item");
}
}
);
I have the following method override to control de contextmenu menuitem selected:
#Override
public boolean onContextItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case 0:
ShowAlert("hello from delete item");
break;
default:
return super.onContextItemSelected(item);
}
return true;
}
In this overridden method, how could I find the item of the list view that was clicked?
You can use the ContextMenu.ContextMenuInfo.
Something like that:
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
int index = info.position;
}
You can also get the exact View for which the menu is being displayed:
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
int index = info.position;
View view = info.targetView;
}
private static final int EDIT_ID = Menu.FIRST + 3;
private static final int DELETE_ID = Menu.FIRST + 4;
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
menu.add(Menu.NONE, EDIT_ID, Menu.NONE, "Edit").setAlphabeticShortcut(
'e');
menu.add(Menu.NONE, DELETE_ID, Menu.NONE, "Delete")
.setAlphabeticShortcut('d');
}
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item
.getMenuInfo();
switch (item.getItemId()) {
case EDIT_ID:
edit(info.id);
return (true);
case DELETE_ID:
delete(info.id);
return (true);
}
return (super.onOptionsItemSelected(item));
}
OK, to solve problem info null ****
use static member and set value from Position of your holder
to save the value in longclick method member for example:-
public class CurrentPosition {
public static int Pos{ get; set; }
}
public bool OnLongClick(View v)
{
CurrentPosition.Pos = Position;
return false;
}
and use in your context select item:
public override bool OnContextItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case 0:
return true;
case 1:
Toast.MakeText(this,CurrentPosition.Pos.ToString(), ToastLength.Long).Show();
return true;
case 2:
Toast.MakeText(this, "Save", ToastLength.Long).Show();
return true;
}
return true;
}
}
C# code