Android: Reference R.string.blah based on a method input - android

I have 3 strings in my strings.xml.
<string name="string1">Hello from string1</string>
<string name="string2">Hello from string2</string>
<string name="string3">Hello from string3</string>
Now, I have a method that I pass a string like "string1" or "string2":
void showStringToast(String sName) {
Toast.makeText(this, getString(R.string.[sName]), Toast.LENGTH_LONG).show();
}
How do I properly reference R.string.sName when sName is being passed as a parameter?

you can pass parameter to your string using like:
<string name="string1">Hello from %1$s (or $d if you want to pass integer) %2$d (second parameter)</string>
Now pass parameter from getstring method:
getString(R.string.string1,first parameter ,second parameter ...);
see this

// try this
void showStringToast(String sName) {
Toast.makeText(this, getString(getResources().getIdentifier(sName, "string", getPackageName())), Toast.LENGTH_LONG).show();
}

I haven't tried this code but I believe you could make use of HashMaps instead.
Declare a static HashMap somewhere, let's say in Constants.java
public static HashMap<String, String> map = new HashMap<String, String>();
then initialize your map. This must be inside a method or constructor
map.put("string1", "Hello from string1");
map.put("string2", "Hello from string2");
map.put("string3", "Hello from string3");
Now you can find your String with something like:
Toast.makeText(this, Constants.map.get(sName).toString(), Toast.LENGTH_LONG).show();
Don't forget to import Constants.java

R.string.something is an integer value that contains a reference to your string. So , R.string.something is like a variable here. Have you ever done such thing that you have generated a variable by appending some string to make it like a variable name and your generated variable name working like a variable ? :)
Instead you can do like this. In your java source file , take your required string values to a String array from your resources. Then use them when necessary. Hope it helps.

Try This way:
void showStringToast(int sName) {
Toast.makeText(this, getString(sName), Toast.LENGTH_LONG).show();
}

Related

Can I modify a Strings.xml file programmatically in Android? [duplicate]

I have declared a string in my strings.xml file , and using it in my activity as R.string.compose_title. (setting it as title i.e. setTitle(R.id.compose_title)). Now in some case I want to edit the string and then use it to set the title . How can I do this ?
P.S. I need to change value of a single string only , So declaring a new strings.xml for each case(which are variable depending upon the user) using localization seems to be a lil inefficient .
One thing what you have to understand here is that, when you provide a data as a Resource, it can't be modified during run time. For example, the drawables what you have in your drawable folder can't be modified at run time. To be precise, the "res" folder can't be modified programatically.
This applies to Strings.xml also, i.e "Values" folder. If at all you want a String which has to be modified at runtime, create a separate class and have your strings placed in this Class and access during run time. This is the best solution what I have found.
example howto:
how? by changing one variable reference to other reference
usage:
setRColor(pl.mylib.R.class,"endColor",pl.myapp.R.color.startColor);
// override app_name in lib R class
setRString(pl.mylib.R.class,"app_name",pl.myapp.R.string.app_name);
base methods:
public static void setRColor(Class rClass, String rFieldName, Object newValue) {
setR(rClass, "color", rFieldName, newValue);
}
public static void setRString(Class rClass, String rFieldName, Object newValue) {
setR(rClass, "string", rFieldName, newValue);
}
// AsciiStrings.STRING_DOLAR = "$";
public static void setR(Class rClass, String innerClassName, String rFieldName, Object newValue) {
setStatic(rClass.getName() + AsciiStrings.STRING_DOLAR + innerClassName, rFieldName, newValue);
}
helper methods :
public static boolean setStatic(String aClassName, String staticFieldName, Object toSet) {
try {
return setStatic(Class.forName(aClassName), staticFieldName, toSet);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return false;
}
}
public static boolean setStatic(Class<?> aClass, String staticFieldName, Object toSet) {
try {
Field declaredField = aClass.getDeclaredField(staticFieldName);
declaredField.setAccessible(true);
declaredField.set(null, toSet);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
#bradenV2 My app is supporting many languages , so I wanted to take a
string from my strings.xml that's currently in use and change that ,
and then use that one – atuljangra Mar 12 '12 at 22:04
ps the above solution is good for example when u want to inject some data in already compiled lib/jar. But if u want localize strings just make folder under res per LANG CODE like values-CC where cc is lang code (values-de,values-cs) etc
then u have 2 choices:
"build in" system dependent language selection - based on device selected lang
via create resources for configuration - you decide which lang show
like this:
configuration = new Configuration(resources.getConfiguration());
configuration.setLocale(targetLocale);
String localized = Context.createConfigurationContext(configuration)
.getResources()
.getString(resourceId);
I don't think you can programmatically customize the R class as it is built by ADT automatically.
I had a situation like this, where one of my strings.xml values had some dynamic piece of it. I set up the strings.xml with a "replacement text" (something like %%REPLACEMENT_EMAIL%%), and when I wanted to use that string programatically, I retrieved the string value of the resource, and replaced instances of that replacement text with the dynamic value (e.g. input by the user).
To be honest, my app has not been localized yet, but I'm still attempting to follow best practices w.r.t. not hardcoding any strings.
Use SharedPreferences instead of a Java class. It will give you more versatility if you decide to take values from the outside (web). Filling Java class in runtime can be useless offline. In case of SharedPreferences you have to ensure they are loaded only once, during app's first start, and then updated only by manual request, as previous import will be used.
myActivity.getSharedPreferences("com.example.imported",0)
.edit()
.putString("The news",getTheNews())
.apply();
Maybe you want to "modify" the string.xml so when it is required by the activity again it uses the new value, for example to keep a new dynamic title after screen rotation.
First, you can't modify the resource. It's already compiled. You can't modify the R class (what for?) all it's atributes are "final".
So, for the example above you can use onSaveInstanceState() and onRestoreInstanceState() for those properties you wanna keep on display.
According to my knowledge, you can't change resource value(R class value) while app running. why don't try to store on shared preference? I recommend you to use shared preference
I used below method to get the key-value pairs from the API and storing it in HashMap globally. If the key value is not found in HashMap then I will search that key in strings.xml file. It will achieve the purpose of dynamically changing the value of key.
public String getAppropriateLangText(String key) {
String value = "";
try {
HashMap<String, String> HashMapLanguageData HashMapLanguageData = gv.getHashMapLanguageData();
value = HashMapLanguageData.get(key);//Fetching the value of key from API
if (value == null || value.length() == 0) { //If Key value not found, search in strings.xml file
String packageName = getPackageName();
int resId = getResources().getIdentifier(key, "string", packageName);
value = getString(resId);
}
} catch (Exception e) {
value = "";
}
return value;
}

Get all String resources used in activity

Is it possible to create a method that would return an array/list of all R.String resources used in an activity?
I'd need something like:
I enter ActivityA
I put to onResume
Log.d(TAG, "Strings used in ActivityA: " + getStringsFromCurrentActivity());
I enter ActivityB and use this method again.
(...)
what is the purpose?
you should define yours Strings in the String.xml file.
Than you should use
String str = getResources().getString(R.string.str_1);
If you want to, you can write a method like:
(but i absolutely see no need to do this)
String [] getStringsForActivity(){
ArrayList<String> al = new ArrayList();
al.put( getResources().getString(R.string.str_1));
al.put( getResources().getString(R.string.xxx));
String[] ar = new String[al.size()];
return al.toArray(ar);
}

Java - Parse - iterate over ParseObject fields

Having a ParseObject object how can I loop through its fields and get the name of the field along with the value of it? This would really help me minimize my code.
Hmm, ParseObject contains key-value pairs, and I think you can't iterate though it. But. I found something called .keySet() method of ParseObject. It returns ... well, the set of keys (excluding createdAt, updatedAt, authData, or objectId). I think you can convert it into an array and iterate trhough it?
Something like this:
Set<String> keySet = parseObject.keySet();
String[] parseKeys = keySet.toArray(new String[keySet.size()]);
for (String key : parseKeys) {
String parseValue = parseObject.get(key);
//do whatever you want
}

Can't readout ArrayList in Android

I deliver a ArrayList to another method, where I just wanna readout a specific String of the list.
public void pruefeWerHat(ArrayList<Teilnehmer> test){
System.out.println(test);
I get this in LogCat
"1 PeterPan 0 0, 2 Hansi 0 0"
now I just want to use the name, but if I say (after sysout)
String name = test.get(1);
the problem he said to is, that he cannot convert from Teilnehmer to String. I also tested Teilnehmer.get(1) but it doesn't work neither.
When you do
System.out.println(test);
the toString() method is automatically used. This method is in the Object class, so all objects in java can call this method.
When you do
String name = test.get(1);
the toString() method is not called on it's own, you have to call it yourself. To do this, simply use
String name = test.get(1).toString();
Also, if you want to change what is printed, you can overwrite the toString() method in your class.
#Overwrite
public String toString() {
String stringToPrint = "This string will be printed";
return stringToPrint;
}
Now when you do
System.out.println(test);
instead of seeing "1 PeterPan 0 0, 2 Hansi 0 0" you will see "This string will be printed" (or whatever you choose to add in your toString() implementation.
When you print test toString function is called so use this in your code
String name = test.get(1).toString();
What are the members of Teilnehmer?
You need to use something like
string name = (Teilnehmer)test[1].Name
where Name is the field you are trying to extract
The get(int index) method available to ArrayList returns type E. In this instance, it returns type Teilnehmer, which is obviously not a String. You can try and cast Teilnehmer (although probably not desirable) to String or simply call the .toString() method (e.g; test.get(1).toString()) inherited from type Object. Or, if desired, calling a method that returns a String. test.get(1).getNameAsString();
The reason you are allowed to call the type in System.out.println(Teilnehmer) is that println makes a call to the object's string representation:
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}

How to concatenate strings and integer into a variable

It is a real silly questions but I can't get it to work. I've used the search option, but couldn't not find my answer for android.
What I would like to do it the following:
In res/strings.xml i've got several strings
<string name="good0">blablabla</string>
<string name="good1">balablabla2</string>
etc
I want to show those strings randomly in a those when something happens:
Toast.makeText(this,R.string.good+(Math.random()*10), Toast.LENGTH_LONG).show();
But this doesn't work.
Thanks a lot for your help!
Use a String Array.
In strings.xml:
<resources>
<string-array name="messages">
<item>blablabla</item>
<item>blablabla</item>
</string-array>
</resources>
Then, in code you will have something like:
String[] messages = getResources().getStringArray(R.array.messages);
Random r = new Random();
String message = messages[r.nextInt(messages.length)];
Toast.makeText(this, message, Toast.LENGTH_LONG).show();
R.string.good is an int because it refers to a Resource. This int IDENTIFIES a string in an XML file. Android provides a getString() for its resource identifiers.
Android Docs on String Resources
You'll have to get the String out of the resource file this way, then concatenate as normal.
You can't do that.
You will have to use a switch block.
String myString;
switch(Math.random() * 10) {
case 0:
myString = getString(R.string.good1);
break;
}
Toast.makeText(this, myString, Toast.LENGTH_LONG).show();
If you have multiple string values or integer values and you to store it in a single string then String Builder is the best for this
type of operation, For Example you have a string array and you want to
store in a single string and then display this string then use this
method. it will work hundred percent and it is too much suitable for
this type of problems.**
String my_str=null;
StringBuilder bldr=new StringBuilder();
for(int j=0;j<5;j++)
bldr.append(phonearray[j]).append(",");
my_str=bldr.toString();
here in this case i am assigning phone array to a single string and
then i will display it etc...

Categories

Resources