I have created controls in android pragmatically by reading an xml
For Example
CheckBox checkbox = new CheckBox(this);
checkbox.setText("Text");
I would like to get the values in the control at a later stage dynamically
View view = this.findViewById(resId);
bool checked = ((CheckBox)view).isChecked();
How do I "resId" for the control created pragmatically.
I tried to use checkbox.getId() but it is returning 0
You better keep reference to your control and use it to set values.
Map<String, CheckBox > checkBoxes = new HashMap<String, CheckBox >();
...
checkBoxes.put("checkBox1", new CheckBox(this));
...
CheckBox checkbox = checkBoxes.get("checkBox1");
But if you really want id you can set your custom id via setId method as #Merlevede suggested but let android generate the id to avoid conflicts. Create a xml resource item:
<item type="id" name="your_super_puper_id"/>
And then use it: xxx.setId(R.id.your_super_puper_id)
To find Views you can use tagging. Using setTag method you can attach any object to a view and then use that object to find view via findViewWithTag method.
String superPuperStringId = "checkBox1";
someView.setTag(superPuperStringId);
...
view = someViewGroup.findViewWithTag(superPuperStringId);
Also you can create your checkbox via xml and assign id there.
You can set a custom ID using checkbox.setID(25) (for example), you need to provide a unique ID. The problem that you may encounter is that there's and ID collision with some other control (if you're also using a layout XML), because the IDs are generated automatically.
I would suggest keeping your checkbox variable as a member of your class, so that yo can access it later on.
Related
Have defined xml for my context menu mymenu.xml.
Want every menu inflated from this xml to provide same unique identifier - so I know it was inflated from mymenu.xml file.
Tried hashCode() or toString() on Menu but found out,that new ContextMenu instance is created on every onCreateContextMenu call and so these values differ.
<menu> tag cannot have some unique attribute set also.
So, my question:
Is it possible to get String containing name of xml from which was menu inflated,( in my case "mymenu"), or some other per-xml unique value, which would not be defined programatically by me?
(for example summing id's from all its MenuItems)
Finally found out, that R.menu.mymenu does that. It returns unique int per xml.
I am attempting to set a Preference layout in code using setLayoutResource() . But this method requires an int id. I have a preset RelativeLayout that I want to pass as an argument, but I get an error saying Preference cannot be applied to RelativeLayout. I suspect it is because I am not passing an R.layout.id. I need this to work because I will addPreferences dynamically using instances of the same layout with different attribute setting. How can I make this work? Thank you. Sample code below.
rLay=(RelativeLayout)View.inflate(Context,R.layout.account_item, null);
nameView =(TextView) rLay.findViewById(R.id.account_name);
numberView =(TextView) rLay.findViewById(R.id.number_name);
pView = new Preference(Context);
pView.setLayoutResource(rLay); ///ERROR HAPPENS HERE///
If you use same layout with dynamically-changing data,
you can create AwesomePreference extends Preference,
then override onBindView(View) to changing TextView's text or something like that.
This is working like ListView's adapter#getView().
Also don't forget to call Preference#notifyChanged() if you changed bound data.
hope this will help.
I use a CheckBox in my Activity, which is defined in "main.xml" (cbSetAll).
I also have a BaseAdapter, using "item.xml", for setting customized ListItems in a ListView in "main.xml".
Now i want to check all CheckBoxes, depending on cbSetAll. When I fetch the value of cbSetAll, the app crashes. I do this by
boolean bCheckAll = ((CheckBox) view.findViewById(R.id.cbSetAll)).isChecked();
to set the CheckBoxes in BaseAdapter by
((CheckBox)view.findViewById(R.id.cbSetItem)).setChecked(bCheckAll);
If I define
boolean bCheckAll = true;
everything works. I think, the error is, that the CB is in "main.xml" instead of "item.xml" and so the "view" is scoping in the Nirvana. Can someone give a hint?
One way to solve it is to create an additional variable in your custom adapter and set this variable from the parent activity. This way you can control the behaviour in the adapter.
You can add this variable to the constructor of the adapter.
You spotted the problem, you can't access views outside a row from inside. A quick way to do this, would be defining bCheckAll as an instance static variable of your Activity.-
static boolean bCheckAll;
In onCreate method, add a listener to cbSetAll CheckBox so that you can update bCheckAll value, and access it from you adapter's getView method.
I'd like to be able to loop through a list of xml layout files instead of having to specify a particular one in the setContentView argument.
Obviously the types are incorrect, but something like:
ArrayList<String> pages = new ArrayList<String>();
//(Where each of the xml pages are stored like R.layout.page1, R.layout.page2, etc)
setContentView(pages.get(0));
Is this possible somehow?
You should use the ViewFlipper widget instead. Here is an example.
It is cleaner to manage the content views and their children widgets this way.
Anyway, the resource IDs can be obtained from names using the Resources.getIdentifier method.
Yes. it's possible. But two notes:
The ids are ints, not Strings.
You need to manage the views inside them properly.
In an application I have created I use the following code to set the image button to a particular resource:
imgBtnCard.setImageResource(this.getResources()
.getIdentifier("com.twp.cptshitface:drawable/" +
cardType + cardDetails[1] , null, null));
I would say that this is what you are looking for:
int resLayoutId = this.getResources().
getIdentifier("your.package.namespace:layout/" +
pages.get(0), null, null);
setContentView(resLayoutId);
// where pages.get(0) returns a string such as "main2"
I've quickly tested this code in the onCreateMethod.
remember to clean your project if you add more layouts and/or resources so the id's are updated!
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
}