I have a set of View instances that each represent some different data object (derived from Java.Lang.Object). I associate each view with its data object by setting the view's tag reference. The views can generate context menus, and in the onCreateContextMenu function I can get the source view and then get the data object from its tag.
My problem is that I can't find a way to associate the data object with the created menu or menu item such that I can get the data item in onContextItemSelected().
How do I propagate the data item to onContextItemSelected()?
UPDATE
From the link posted by #asktomsk it looks like what I want to do is only possible (without a lot of subclassing) if the originating view is a ListView. Having also read this on the android developer site I suspect that long-tough context menus are probably not advisable anyway, and that I should find a different mechanism.
Check the MenuItem.getMenuInfo() data. It contains information about context menu caller.
Some explanation you may found here:
Identifying the view selected in a ContextMenu (Android)
Related
To use ActivityOptionsCompat.MakeScaleUpAnimation(), I need access to the View from where the animation originates. I use MvvmCross, so I need to pass via a MvxFragmentsPresenter (shouldn't be relevant to the problem). A ViewModel request can contain key/value parameters. So I attach a Tag to each RecyclerView item and then pass on that Tag as a parameter in the ViewModel request, as done here. I can access this tag in the presenter.
Now inside the presenter I need to find the RecyclerView item that was clicked. I want to do this as follows:
View contentFrame = Activity.FindViewById(Resource.Id.content_frame);
View recyclerView = contentFrame.FindViewById(Resource.Id.recycler_view);
View item = recyclerView.FindViewWithTag("mytag");
Unfortunately this results in null. I can access the contentFrame and the recyclerView, but not an item by Tag. However I can even get the first item using:
recvddfg.GetChildAt(0);
... and access the Tag! So it's strange that FindViewWithTag isn't working. Does anyone have an idea?
After searching for hours, I decided to post this question. Then looked back at it and found the cause: I was searching for an item with a tag of type string, while I should have been searching for a number... You can use any type you want with a Tag, so in your case it might be different if you have the same problem. You just need to be consistent.
when I share an array list from the Main Activity to an Custom View for example will it be passed by reference or copy, my doubt is if the MainActivity add new elements to this list that was passed the Custom View will get the change. I want to build an application that the main activity will be processing a lot of data and putting this in an array, this array will be passed to a custom view that through canvas will draw a graph with the information inside of the list that was passed, so that is why this information is so important. Any kind of help will be precious, Cheers.
It is passed by reference yes. All objects are. You can read all about it HERE
In fact I'm working on an android project I have a list of events, when I click on an event I can pass the name of the event and its image but I can not put the description in a tabhost how can I do it?
Option 1:
You can try using setTag method on each row which stores your description.
setTag(Object tag)
Sets the tag associated with this view.
Option 2:
I have similar situation in my project. This is how I achieved
When I created the list, I have created array of string object. I keep this as a global object in MYProjectApplication.java file. So it is available everywhere.
When the list is clicked I get the position and refer the corresponding description from the global string array.
On subclasses of View there is a getTag() method, which returns the android:tag attribute's value from .xml.
I would like the same for a MenuItem... is it okay to just cast it to a View?
Because item elements also allow a tag attribute in .xml...
Update: My goal with this is setting a tag in .xml, i.e. "notranslate", and querying it at runtime (we localize by hand at runtime, don't ask...)
It is always alright to cast, however, casting any Interface cannot be checked at compile time, only runtime. This is normally the reason many do not recommend casting an Interface that you have no control over. Having the proper error checking code is the best way to insure that such a cast does not break your code.
For the casting, it doesn't really matter whether the MenuItem is an Interface or a View, but the object it references must be one of View's subclasses, if not a View itself. If you are going to cast it, try the cast and catch a ClassCastException just in case as this is the error that will be thrown in runtime.
Another option is that since the MenuItem is simply an interface, you can easily just create a View subclass that utilizes MenuItem allowing you to do the cast. If you are doing a custom ContextMenu as many launchers do, then chances are your answer is nearly complete.
Hope this helps,
FuzzicalLogic
MenuItem is an interface. Any class can implement this interface and so it will not always be safe to cast the MenuItem to a View. You can use the "instanceOf" operator to test to see if the object that implements the MenuItem interface is indeed a View or not.
I understand that you want to define a flag in the XML definition of the menu and then at run time interrogate that flag to make a programmatic decision.
The Menu Resource Documentation records what attributes can be set in the XML. You can consider using (abusing) one of those settings such as the "android:alphabeticShortcut" to encode the flag and use the MenuItem::getAlphabeticShortcut() method to get the value. This does not require casting - it just uses the existing fields in the MenuItem XML construct/class for your own purposes.
Perhaps a less hacky way to do this is to keep a simple table in a separate assets file that lists the menu item identifiers and the special behavior associated with that identifier such as to translate or not to translate.
Alternatively create a simple class that has a table with this configuration information hard coded using the logical "#[+][package:]id/resource_name" resource identifier as the keys to the table. While this doesn't keep it all in one place (in the XML) it does it in a manner that is not encoding information in unused attributes, or relying on the ids not changing. The "table" could be implemented as a static method with an embedded switch statement allowing code such as "if (TranslationTable.shouldTranslate(menuItem.getItemId())) { do translation }"
I had a similar problem in that I wanted to associate some arbitrary data with each menu item so that I could handle menu items in a generic way without having to use hardcoded checks for individual item ids in code.
What I did was for a particular menu item (e.g. #+id/foo) There was an a TypedArray that was defined using the same name as the menu item ID. You could do this with other types of resources as well.
So to do the association, you get the resouce entry name (foo in my example) and then use that to look up the id of the other resource of a different type (#array/foo in my example).
In my handler for menu I had code like this:
Resources resources = getResources();
String name = resources.getResourceEntryName(item.getItemId());
int id = resources.getIdentifier(name, "array", "com.example");
if(id != 0)
{
TypedArray data = resources.obtainTypedArray(id);
// Use the typed array to get associated data
}
EDIT:
Actually it is even easier than that. There is nothing special about the ids on menu items other than you don't want multiple menu items with the same id. The id does not have to be of the form #+id/foo. It can actually also refer to other resources. So in my example above, instead of having the menu have an id of #+id/foo and using the resource manager to use that to find #array/foo, I changed to actually have the menu item have the id of #array/foo.
Now in my onOptionsItemSelected I have this:
Resources resources = getResources();
if("array".equals(resources.getResourceTypeName(item.getItemId())))
{
TypedArray data = resources.obtainTypedArray(item.getItemId());
// Use the typed array
}
I'm wondering a simple way to find back the object corresponding to the clicked item..
They're tons of examples on the web on how to figure out the ListView setup with the setListAdpater, but much less on how to well handle its listener.
Is "by position" the only way ?? I'm wondering a possibility to associate the objects itselves to the adapter, to not have to use their position in list (or even the displayed String!) to find back the Object referred by the clicked label..
Position is what is used always. The ListView works with using the position.
But if you want to access the ListAdapter and get a value out by providing a string, than you will have to extend ListView and implement that functionality yourself. You can overwrite the different methods that handle adding and removing and keep a HashMap where you keep the string representing the object. Then through a getObject(String key) you return the object that is in the hashmap for that key.