Context Menu with TabHost issue - java

I have a TabHost with 2 Fragments, both lists. The onCreateContextMenu works fine for both, but both onContextItemSelected are "pointing" to the first Fragment class. I'm using different names for the lists in the XML files, so the ID isn't the same.
Here is the code for both onCreateContextMenu
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
int itemID = info.position;
Map m = (HashMap) this.listView.getAdapter().getItem(itemID);
menu.setHeaderTitle(getString(R.string.options));
menu.add(0, v.getId(), 0, activity.getString(R.string.delete));
}
And here onContextItemSelected for the first Fragment, second one is pretty much the same code just changing var names. In fact this doesn't change anything to the question, since this method only runs on the first Fragment, even when I'm on the second list.
#Override
public boolean onContextItemSelected(MenuItem item) {
ContextMenuInfo menuInfo = (ContextMenuInfo) item.getMenuInfo();
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
int itemID = info.position;
Map m = (HashMap) this.listView.getAdapter().getItem(itemID);
processId = Integer.parseInt(m.get("processId").toString());
activity.setSupportProgressBarIndeterminateVisibility(true);
runBackground(activity.getString(R.string.accessingECM), false, false, ACTION_REMOVE);
return true;
}
This is how I register for context menu on the onActivityCreated method. Note that the onCreateContextMenu works for both Fragment.
listView = (ListView) this.view.findViewById(R.id.listProcess);
registerForContextMenu(listView);
I tried to change the menu.add() 1st and 3rd parameters to (1,1) and (1,2). Also tried both to be Menu.NONE. Still doesn't work.
Thanks

For a tabhost (in my experience) you need to set up a single onCreateContextMenu in the activity for the tabhost and use a switch to get the appropriate menus/actions.
Example:
// ***************************************************************
// Create the various context menus depending on which list it is from
// ***************************************************************
#Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
switch (v.getId()) {
case R.id.list1: {
menu.setHeaderTitle("Tool CC Menu");
menu.add(0, v.getId(), 0, "Edit/Add Cutter Comp Info");
menu.add(0, v.getId(), 0, "Clear Cutter Comp Info");
break;
}
case R.id.list2: {
menu.setHeaderTitle("WPC Menu");
menu.add(0, v.getId(), 0, "Edit WPC Info");
menu.add(0, v.getId(), 0, "Clear WPC Info");
break;
}
}
}
// ***************************************************************
// Create the various context menu actions based on which list
// ***************************************************************
#Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
cc_id_int = (int) info.id;
if (item.getTitle() == "Edit/Add Cutter Comp Info") {
showDialog(CCEDIT_DIALOG_ID);
} else if (item.getTitle() == "Clear Cutter Comp Info") {
showDialog(CLEARCC_DIALOG_ID);
} else if (item.getTitle() == "Edit WPC Info") {
removeDialog(WPCEDIT_DIALOG_ID);
showDialog(WPCEDIT_DIALOG_ID);
} else if (item.getTitle() == "Clear WPC Info") {
showDialog(CLEARWPC_DIALOG_ID);
}
return super.onContextItemSelected(item);
}
Hope this helps!

Related

mend.findItem explanation and confusion

I'm new to android development and kinda to Java as well.
I'm learning how to add buttons to actionbar - everything is working, but I don't understand few things.
//Showing small icons at actionbar
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
menuItem = menu.findItem(R.id.recBin); // Finds the button in Actionbar and gets the ID
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.recBin: // Actions for delete button
dbHandler.remove(getID());
displayTaskList();
menuItem.setVisible(false); // Hide the button
break;
case R.id.editBtn: // Actions for editbutton
Toast.makeText(MainActivity.this,
"EDIT", Toast.LENGTH_LONG).show();
break;
case R.id.closeBtn:
Toast.makeText(MainActivity.this,
"CLOSE", Toast.LENGTH_LONG).show();
break;
default:
break;
}
return true;
}
This line: menuItem = menu.findItem(R.id.recBin); Is for what exactly? I took it off and my app crashed, so I understand that it's mandatory. What I don't understand is what icons ID should I put at bold space? It has to be from "menu" right, but does it matter which id I take? For instance, if I took R.id.closeBtn instead of recBin? As long as it's an id from menu, it works?
P.S. I hope this isn't a terrible question [probably is] and I'm sorry if so.
Solution:
Turns out you can simply get ID's. Stupid and simple.
private MenuItem item1, item2, item3;
//Showing small icons at actionbar
#Override
public boolean onCreateOptionsMenu(Menu menu){
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
item1 = menu.findItem(R.id.recBin); // Rec button
item2 = menu.findItem(R.id.editBtn); // Edit button
item3 = menu.findItem(R.id.closeBtn); // Close button
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.recBin: // Actions for delete button
dbHandler.remove(getID());
displayTaskList();
item1.setVisible(false); item2.setVisible(false); item3.setVisible(false); // Hiding all buttons
break;
case R.id.editBtn: // Actions for editbutton
item1.setVisible(false); item2.setVisible(false); item3.setVisible(false); // Hiding all buttons
break;
case R.id.closeBtn:
item1.setVisible(false); item2.setVisible(false); item3.setVisible(false); // Hiding all buttons
break;
default:
break;
}
return true;
}
It's a reference to MenuItem, but it would be easier if you do:
case R.id.recBin: // Actions for delete button
dbHandler.remove(getID());
displayTaskList();
item.setVisible(false); // Hide the button
break;
You can safely remove the reference afterwards

Setting text color of EditText

I have a dialog that triggers on EditText's context menu. Dialog sets the amount of red, green and blue of EditText. The problem is that runtime error occurs when I click positive button. Items above works fine, they set the color of text in EditText as it should, but rgbDialog don't.
I think that the problem occurs here:
etRed = (EditText)findViewById(R.id.etRed);
etGreen = (EditText)findViewById(R.id.etGreen);
etBlue = (EditText)findViewById(R.id.etBlue);
But I don't know how to initialize etRed, etGreen and etBlue right. I think that I should place something before findView like
etRed = (EditText)Dialog.findViewById(R.id.etRed);
But don't know what, because everything is happening in the same method (onContextItemSelected)
#Override
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()){
case R.id.white:
temp.setTextColor(Color.WHITE);
break;
case R.id.red:
temp.setTextColor(Color.RED);
break;
case R.id.green:
temp.setTextColor(Color.GREEN);
break;
case R.id.rgb:
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle("choose the amount of red green and blue");
LayoutInflater inflater = this.getLayoutInflater();
dialogBuilder.setView(inflater.inflate(R.layout.colors, null));
dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
etRed = (EditText)findViewById(R.id.etRed);
etGreen = (EditText)findViewById(R.id.etGreen);
etBlue = (EditText)findViewById(R.id.etBlue);
red=etRed.getText().toString();
green = etGreen.getText().toString();
blue = etBlue.getText().toString();
intRed = Integer.parseInt(red);
intGreen = Integer.parseInt(green);
intBlue = Integer.parseInt(blue);
temp.setTextColor(Color.rgb(intRed, intGreen, intBlue));
}
});
dialogBuilder.setNegativeButton("CANCEL", null);
AlertDialog alertDialog = dialogBuilder.create();
alertDialog.show();
break;
default:
break;
}
return super.onContextItemSelected(item);
}
EditText temp is set like this, and works fine for items above rgb
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.context, menu);
temp = (EditText)findViewById(v.getId());
super.onCreateContextMenu(menu, v, menuInfo);
}
you can have something like below to call findViewById from correct layout:
View dialogView = inflater.inflate(R.layout.colors, null);
dialogBuilder.setView(dialogView );
and when you are calling findViewById in onClick you can have like:
etRed = (EditText)dialogView.findViewById(R.id.etRed);
etGreen = (EditText)dialogView.findViewById(R.id.etGreen);
etBlue = (EditText)dialogView.findViewById(R.id.etBlue);
Check if this helps.

How to show buttons in a list item on long press

I'm trying to mimic the behavior of twitter application. When you long press an item (tweet) four buttons show up on that list item. Any of those buttons can be pressed to take the user to another screen.
Similarly, I have a list like this:
lv.setOnItemClickListener(new android.widget.AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View view, int arg2,long arg3) {
startActivityWhenListItemClicked(view);
}
});
The above code works when a list item is clicked.
How can I implement long-press and show few buttons on the list item? I would appreciate any tutorial or an example.
Exactly equal that the onClickListener(), but with onLongClickListener() implementing onLongClick(). I'd go by registering each row for contextual menu, this way:
context.registerForContextMenu(yourView);
And then simply implement the contextual menu function overridings.
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
menu.setHeaderTitle("My twitter menu");
menu.add(Menu.NONE, 0, 0, "Remove");
}
#Override
public boolean onContextItemSelected(MenuItem item) {
final int mId = item.getItemId();
switch (mId) {
case 0:
...
break;
default:
break;
}
return true;
}

Get position of selected item...?

I'm rather new to Android. Here's part of code:
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Note selectedName = adapter.getItem(position);
adapter.removeItem(selectedName);
As you see, position means selected item position. That's good. But I'd prefer long clicks:
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.ctxmemu_delete:
** I need to use POSITION mentioned above! **
But in this method getSelectedItemPosition returns position -9995845834585 (or smth like that)
Or it gives error (can't move cursor to position - I use SQL in my app)
How can I get position from list properly?
P.S. sorry for my bad English :(
UPD:
I've added this to my SQL Adapter:
public int getPosition(){
return cursor.getPosition(); }
and modified:
case R.id.ctxmemu_delete:
int position = adapter.getPosition();
Note seln = adapter.getItem(position);
adapter.removeItem(seln);
return true;
for now it works...but I think it's so ugly...
You just need to use onListItemLongClick() instead of onListItemClick().
Why don't you use a onListItemLongClick listener instead of going for the context menu ?
protected void onListItemLongClick(ListView l, View v, int position, long id) {
super.onListItemLongClick(l, v, position, id);
Note selectedName = adapter.getItem(position);
adapter.removeItem(selectedName);
}
public boolean onContextItemSelected(MenuItem item) { ... }
Since you are using ContextMenu this is a little different from ItemClickListener
You can use MenuInfo for getting position in ListView
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
Where it has int property info.position that returns position in the adapter for which the context menu was displayed.
Note: You can also have look at OnItemLongClickListener with works similar.

Please help me set up a Context Menu in an AlertDialog

I've been working at this all day, and I'm really close but just can't get this to work. I have a button that pulls up an AlertDialog populated with saved entries that include Name and Price. Right now, I can click an item in the Dialog and have it automatically fill in the Name and Price fields in my activity. I want to also be able to long press an item and receive an option to delete it. This is my first try at an Android app, and a lot of this is repurposed from the Notepad Tutorial. Two things I can't figure out:
1) Is my registerForContextMenu sufficient/correct?
2) What am I doing wrong with my onCreateContextMenu?
Thanks.
savedItems.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
cDbHelper.open();
mNotesCursor = cDbHelper.fetchAllSaved();
startManagingCursor(mNotesCursor);
// Create an array of names and corresponding prices from db
String[] from = new String[]{SavedItemsDbAdapter.KEY_NAME, SavedItemsDbAdapter.KEY_PRICE};
// and an array of the fields we want to bind those fields to
int[] to = new int[]{R.id.text1, R.id.text2};
// Now create a simple cursor adapter and set it to display
SimpleCursorAdapter saved =
new SimpleCursorAdapter(NewEntry.this, R.layout.saved_row, mNotesCursor, from, to);
// Build an AlertDialog to hold this list
AlertDialog.Builder builder = new AlertDialog.Builder(NewEntry.this);
builder.setTitle("Choose from list");
// IS THIS SUFFICIENT TO REGISTER FOR CONTEXT MENU?
registerForContextMenu(v);
builder.setAdapter(saved, new DialogInterface.OnClickListener() {
// When an item from the list is clicked, it automatically populates the name and price fields in activity
#Override
public void onClick(DialogInterface dialog, int item) {
Cursor c = mNotesCursor;
c.moveToPosition(item);
Intent i = new Intent(NewEntry.this, NewEntry.class);
i.putExtra("name", c.getString(
c.getColumnIndexOrThrow(SavedItemsDbAdapter.KEY_NAME)));
i.putExtra("price", c.getString(
c.getColumnIndexOrThrow(SavedItemsDbAdapter.KEY_PRICE)));
startActivityForResult(i, ACTIVITY_AUTO);
finish();
}
// TRYING AND FAILING TO SET UP A CONTEXT MENU - the goal is to be able to long press,
// have a "Delete?" option pop up, which will delete the entry when clicked
#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);
}
public boolean onContextItemSelected(MenuItem item) {
switch(item.getItemId()) {
case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
mDbHelper.deleteItem(info.id);
return true;
}
return false;
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
I just found
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
to be called, but not
#Override
public boolean onContextItemSelected(MenuItem item) {
in my subclassed AlertDialog:
public class MyAlertDialog extends AlertDialog implements
OnCreateContextMenuListener {
Perhaps this is useful to someone else as I'm pretty sure you have meanwhile solved your problem at hand.
You only need implement the following function. It will work.
#Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
{
Log.e(LOGTAG, "Tao menu");
if(v == expList)
{
super.onCreateContextMenu(menu, v, menuInfo);
//AdapterContextMenuInfo aInfo = (AdapterContextMenuInfo) menuInfo;
// We know that each row in the adapter is a Map
//HashMap map = (HashMap) simpleAdpt.getItem(aInfo.position);
menu.setHeaderTitle("Options");
menu.add(1, 1, 1, "Reprint");
menu.add(1, 2, 1, "Void");
menu.getItem(0).setOnMenuItemClickListener(new OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem clickedItem)
{
return true;
}
});
menu.getItem(1).setOnMenuItemClickListener(new OnMenuItemClickListener()
{
public boolean onMenuItemClick(MenuItem clickedItem)
{
return true;
}
});
}
}
Is my registerForContextMenu sufficient/correct?
You are registering a context menu for whatever savedItems is. If that is what you want the context menu on, then you are OK.
If your goal is to have a context menu on the items in the list in the dialog, your approach is wrong. You will not be able to use AlertDialog.Builder. You will need to create a custom subclass of AlertDialog, so you can override onCreateContextMenu() there.

Categories

Resources