Android Button integer ID - android

I would like to have a function that if called can be passed the name of the button and then change the text of said button. I have attempted to use the function findViewById but it wont let me pass a string as it takes a int. This is my question, how can i store the integer value of the Button id's so i can pass to this function?

You could use tags if you need to deal with Strings. Set a tag on the Button using the android:tag xml attribute or setTag. Then you can use findViewWithTag to get a reference to the button.
But it'd probably be easier to just use IDs referenced from the resources object R: R.id.button

Related

Android databinding setText() over model binding

In my xml I have a line android:text='#{entry.printTitle}'
In my adapter I set entry: binding.setEntry(item); in bind() method.
For some occasions I want to set that field manually with binding.entryTitle.setText("some other title"), but it doesn't work. How can I set that field without affecting entry, which is immutable?
You can not override values of binding variables. If you want change dependent views, you have to change its variable value.
You can take another variable for this purpose. And set value in this second variable when you want. Just make this second variable null when you have done.
android:text='#{entry.fakeTitle ?? entry.printTitle}'
Now when you want change title but not its variable then set value in fakeTitle.
binding.getEntry().setFakeTitle("testing");
When you have done make it null so text will be printTitle again.
You have to use ObservableField<String> or LiveData, if you are changing value programmatically. If you are extending by BaseObservable then you have to make fakeTitle #Bindable and notify after changing.

Semantics - Android EditText Class

I'm struggling a bit with some semantics on some basic Android/Java development. If I have the following code (which works) to gather user input from a textfield:
final EditText userInput=(EditText) findViewById(R.id.txtUserInput);
Is userInput an object or a variable? My understanding that it is an object being instantiated form the *EditText * class. What does the (EditText) do to the left of the findViewById. When I see open parens, I think casting. Can anyone provide some simple clarity?
You are correct in saying that userinput is an EditText Object, to be more specific it is an object that is a subclass of View. Everything you get back from the findViewbyId() method will be a View, which you then need to cast to the proper Object. The (EditText) is casting the View you got back from your xml to an EditText. This allows you to access methods from the EditText that are available to the EditText class in particular.
So whenever you use findViewById() you also need to cast the View you get to the Object that it represents.
Let me know if you need further help.
-Dejan
userinput is an object.
findViewById(xxx) returns a View object, but in your case you know that it will return an EditText. Therefore its possible to cast it with (EditText). And you can cast it from a View to EditText since EditText extends View.
When you have cast it to EditText you are able to find all methods exposed by EditText instead of only the methods exposed in View.

How can I add multiple tags for one view directly in XML?

As the question states I simply want to add more than one tag to an XML View. For example, say I want to set an array of strings AND a separate string from my resources. I know how to do them individually but I want to know if there's a way of attaching more than one tag to a view directly within the XML code.
Edit:
My plan was to have a LinearLayout (l#1) that contained a dynamic amount of of a different LinearLayout (l#2) and within that View there would be a Spinner and an EditText. I need one tag for the hint of the EditText and the other for the array of strings to populate the Spinner. In the entire layout there are a multiple l#1 each using l#2 to populate it dynamically and each needing different hints and string arrays based on what they are used for.
My next idea was to add a integer as a tag to represent l#1 and and use a Switch/Case block in my code to populate the children of l#2 with the right hints and string arrays.
I don't think this is possible in XML, but in code what you could do is create a custom object which holds the strings you require and set that as the tag.
class CustomTagObject {
public List<Strings> strings;
public String myString;
}
Then later
CustomTagObject tagObj = new CustomTagObject();
tagObj.strings = new ArrayList<Strings>("String 1", "String 2");
tagObj.myString = "String from resources";
view.setTag(tagObj);
If you explain why you want to hold these items as the tag, I may be able to help you find an alternative approach?
Above solution works, but the usage is wrong(it will add extra overhead on your end to manage the key/value map).
The better way to achieve above is to use an overloaded method of setTag which allows you to specify id associated with the value.
Method signature:
public void setTag(int key, Object tag)

MenuItem#getTag()

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
}

Pass Control By Name To findViewById

If you got:
Button btn = (Button) findViewById(R.id.widget28);
where "widget28" is the name of your button, how can you pass this
into the findViewById as a String? or get it from R class as a string?
I want to get the Button instance by string and not by the hard code R.id.widget28 reference.
thanks
Note that findViewById expects an int, not a string, so not sure what you're trying to achieve here.
But the general way to get a string from its resource id is getString(R.string.theId). See the Context API docs.
I don't believe even with reflection that you can get the variable's name, widget28, if you actually need it for some reason. You could look into using the button's android:tag element to store it in the XML file, you'd then retrieve it in code by using yourButton.getTag(), but I'd look into designing it differently.

Categories

Resources