android - Switching strings in a textView dynamically - java

I am trying to switch the android:text of a textview with various strings that are to be dynamically retrieved from my strings.xml. When the user presses the button on the grid, it will return a unique identifier. I want to use this identifier to dynamically load a string into the Pronoun textView.
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
TextView Pronoun = (TextView) findViewById(R.id.Prounoun);
chosen = ((TextView) v).getText();
//Inserts the identifier of what button was pressed into the local string chosen".
Pronoun.setText("R.string.Pronoun_" + chosen);
}
}
When the button 'a' is pressed, 'chosen' holds the letter 'a', when joining this to the string naming format "Pronoun_", resulting in "Pronoun_a". The intention was to call upon the string at this location. In reality, the text is literally "R.string.Pronoun_a" instead of retrieving the actual string content of Pronoun_a. If the button 'b' is pressed, I want the string content of 'Pronoun_b' to show in the textView. I am new to java, merely trying to recreate a technique I learned in another language. Is there a way to do this?

Use this (with your actual package name):
String resKey = "your.apps.package:string/Pronoun_"+chosen;
int resId = getResources().getIdentifier(resKey, null, null);
Pronoun.setText(resId);
Also see the API Docs.
Note: As AND_DEV already mentioned, you'll have to use ActivityName.this.getResources().

instead of
Pronoun.setText("R.string.Pronoun_" + chosen);
try below line
Pronoun.setText(ActivityName.this.getString(R.string.Pronoun_) ++ chosen);
it will work in activity context, but in onclick i think you should use ActivityName.this. you can also use context variable if you already created. here ActivityName is you activity name of which ur code is written .

Related

Android programming: How to make language change permanent in onItemSelected adapter in a spinner

I'm new to android programming and I would like to do the following:
I have a spinner which lets you change language. I have set it up and it works quite well. However the issue is that it does not remember the chosen language (in the spinner). So if you were to close the app and restart it, it will revert to the first item on the spinner which is english.
I want to change the function in such a way that once you select an item, it remembers it.
I've set up a shared preference which remembers which language is picked. However I can't make the shared preference the lead since then I could never change the chosen language, and if I make the chosen language the lead then the preference will always follow the chosen language even at the start where the chosen language should actually follow the preference. Here's the code that I have now. I hope anyone can help me we this since I've been breaking my brain over it for a while now
pref_language = pref.getString("language", "en");
//pref_language_begin = pref.getBoolean("language_begin", false);
final Spinner spinner_languages = (Spinner) findViewById(R.id.spinner_languages);
spinner_languages.setAdapter(new CustomSpinnerAdapter(MainActivity.this, R.layout.customspinneritem, languages, language_flags));
spinner_languages.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
parent.getItemAtPosition(position);
language_chosen = (String) parent.getItemAtPosition(position);
if (!pref_language.equals(language_chosen)) {
SetLocale(language_chosen);
pref_language = language_chosen;
edit.putString("language", pref_language);
//edit.putBoolean("language_begin", true);
edit.apply();
recreate();
}
else{
}
}
The customspinneradapter is just there to let me select both a language and a flag for it.
I think I might need a second preference but I have no idea on how to implement it. The leading language at start up should be the preference but the language after choosing one in the spinner should be the chosen language. I was thinking about using an onclick listener but I'm not sure I should with spinners.
Surely there must be a more simpler way and I'm just not thinking straight.
Hope you guys can help me out!
I will give you couple suggestions..
Name your variables with the "cammel case" technique. For example:
spinner_languages shoud be named spinnerLanguages . Be a pro :)
Make a key for languages in shared preferences as a global and constant variable to use it everywhere in a class or classes and prevent typo mistake (if you don't know what is 'global variable" please google it):
static final String LANGUAGES_KEY = "languages";
Just when you start your activity ( onCreate() method but before super.onCreate(savedInstanceState); ) read your shared preferences and set language to the app:
// language from android system
String langSystem = Locale.getDefault().getLanguage();
String lang = sharedPreferences.getString(LANGUAGES_KEY, langSystem);
// update language
SetLocale(lang);
After that find the right language index for spinner (for example by using for loop)
and use:
spinnerLanguages.setSelection(languageIndex)
just use setSelection method for initial selecting item after setting adapter (position must be smaller than list items count, without adapter set spinner have 0 items)
spinner_languages.setSelection(position);
position may be picked e.g. by iterating through languages array (passed to adapter) and comparing each lang to pref_language
int position = -1;
for(int i=0; i < languages.size(); i++) {
if(pref_language.equals(languages.get(i))){
position = i;
break;
}
}
if (position >=0) { // found
spinner_languages.setSelection(position);
}
check out THIS topic about spinner selection

How to get drawable name from imageView

I have an app that create a random image when the activity opens. There are like 30 images in the random image array. The image is generated, but what I want is to write the drawable name into a textview. It looks like this:
ImageView RImage= (ImageView) findViewById(R.id.image);
RImage.setImageResource(generator());
Drawable myDrawable = RImage.getDrawable();
TextView writeID = (TextView) findViewById(R.id.idtext);
writeID.setText(String.valueOf(generator()));
}
private int generator() {
TypedArray imgs = getResources().obtainTypedArray(R.array.list3);
int imgid = imgs.getResourceId(new Random().nextInt(imgs.length()), -1);
imgs.recycle();
return imgid;
}
Currently I receive numbers, and I cant figure out how can I convert the int to a string, or how can I use the generator to generate a string, display in the textview and then convert it to int to display it in the imageview.
I created an another activity where I can pick the image I want to see from a spinner, it simply send the selected option with string to the next activity on button press, and in the other activity i remove the .png and res/drawable/ from the string, and convert the string into an int to display the image.
Bundle extras = getIntent().getExtras();
String transportItemChosen = extras.getString("SpinnerValue");
transportItemChosen = transportItemChosen.replace(".png", "");
transportItemChosen = transportItemChosen.replace("res/drawable/", "");
String uri = ("#drawable/" + transportItemChosen);
int id = getResources().getIdentifier(uri, null, getPackageName());
ImageView mImageView;
mImageView = (ImageView) findViewById(R.id.selectedimage);
mImageView.setImageResource(id);
So I need the generator to generate to string and then convert it to int. Thanks!
Change your code by converting your int ids into String names by Using the method
getResourceEntryName(int id);
Change the line:
writeID.setText(String.valueOf(generator()));
To Something like:
writeID.setText(getResources().getResourceEntryName(generator()));
And for Viceversa:
And if you are having a String lets assume this String you get from a textView or using above method to convert it back to an int id you do the following:
int id= getResources().getIdentifier("your_string_here", "drawable", getPackageName());
And if you are calling the code from a Fragment not an Activity remember to put getActivity() before calling getResources()or before calling getPackageName().
I have not tested the code as I am typing, but I am sure it will work (may be a typo) for more information consider visting the Documentation on Resources from this official link.
If I understand you correctly, what you need is to take a look at getResourceName(int) method - it returns resource name by its id. Also you can use getIdentifier(String,String,String) method to retrieve resource id by its name.
If you want to display name of the randomly picked image, you should save the generated resource id into the variable and get corresponding resource name for it instead of calling generator() method twice as you'll get two different ids.

SharedPreferences String Set data lost after app kill (android emulator)

I am running this on an emulator: 5554:Nexus_5_API_22_x86.
I am trying to learn SharedPreferences and have written a simple test program.
It contains two buttons: one adds a String + random # to a set which will be stored in SharedPreferences, and the other prints the contents of that set.
Whenever I press the square button on the bottom right hand of the screen and press 'x' to close the app window, then relaunch the app, the contents of the set are reset - in other words, printing the set yields nothing.
However, if I exit the app using only the back button, the contents remain - in other words, printing the set yields whatever was in it before.
Java:
...
public class MainActivity extends AppCompatActivity
{
final int PREF_MODE_PRIVATE = 0;
TextView output;
Set<String> testSet;
Random randomGenerator = new Random();
SharedPreferences data;
SharedPreferences.Editor dataEditor;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
output = (TextView) findViewById(R.id.textView); //getting the output textfield
data = getPreferences(PREF_MODE_PRIVATE);
//If first-time setup has not been completed, execute the following block
//I don't want the String Set to be reset to empty every time the app is launched
if(data.getBoolean("initialized", false) == false)
{
//Adding the empty set to storage
testSet = new HashSet<String>();
dataEditor = data.edit();
dataEditor.putStringSet("testSet", testSet); //Add the empty Set to storage
dataEditor.putBoolean("initialized", true); //Set initialized flag to true
dataEditor.apply();
}
}
public void printTestSet(View view)
{
output.setText(""); //Clears the text field
Set<String> toBePrinted = data.getStringSet("testSet", null); //Gets the String Set
//Prints content of the String Set
if(toBePrinted != null)
{
for(String word : toBePrinted)
{
output.append(word + '\n');
}
}
}
public void addToTestSet(View view)
{
//Generate a string followed by a random number and add it to the String Set
int randomInt = randomGenerator.nextInt(1000);
data.getStringSet("testSet", null).add("NEW STRING #" + randomInt);
}
}
The button that prints the String Set calls printTestSet and the one that adds a String to the Set calls addToTestSet.
Upon creation, the app uses a simple boolean to check if it has been initialized the for the first time. If not, it adds an empty String Set to storage and sets the boolean to true. If the boolean is already true (meaning it has already added the empty string set), that step is skipped.
You need to either commit your data either realtime (where you are doing apply) or in application life cycle handler onpause (when your app goes to background). Use option 1 when you have little data or 2 when you have large amount of data to commit.
It looks like you're not saving the shared preferences in addToTestSet.
When you do getStringSet and then add, you need to again save the string Set back into shared prefs like you do in your onCreate() using dataEditor.apply().
Or if you want to be a bit more efficient, you can save your stringSet in the activity's onPause() method to prevent constantly writing to SharedPrefs
When you hit back, your app process isn't being killed, which means when you open it up again the Android system is restoring whatever it can (what was written in textViews, checkboxes that were checked, etc. simple things like that). What you see in the box might not actually be getting populated by SharedPrefs.

(Android) Changing text color in strings.xml

First, depending on the user's actions, I want to retrieve a certain strings from my strings.xml resource file:
String option1 = context.getString(R.string.string_one)
String option2 = context.getString(R.string.string_two)
String option3 = context.getString(R.string.string_three)
Then, I pass these strings as String[] options to a custom adapter for a ListView
where I set the text of a TextView
public ChoicesAdapter(Context context, String[] options) {
super(context, R.layout.choice_option_layout_2,choices);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater MyInflater = LayoutInflater.from(getContext());
View MyView = MyInflater.inflate(R.layout.option_list_layout, parent, false);
String option = getItem(position);
TextView textView = (TextView) MyView.findViewById(R.id.textView);
textView.setText(Html.fromHtml(option));
return MyView;
}
I want different strings in my strings.xml file to have different colors or different formatting. For example, here is one of my strings:
<string name ="exit"><![CDATA[<i>exit</i>]]></string>
However, when this string is displayed on the screen, it shows as: "<i>exit</i>"
So, I'm guessing somewhere in my method I am losing the string.xml resource's formatting. How can I get it so instead of showing "<i>exit</i>", it will show "exit" on the screen?
I am thinking my problem is where i use .getString(). Is this somehow ignoring the formatting that I added to it in the .xml file?
Check out http://developer.android.com/guide/topics/resources/string-resource.html#FormattingAndStyling - their example is:
<string name="welcome">Welcome to <b>Android</b>!</string>
It says you can use <b>text</b> for bold text, <i>text</i> for italic text, and <u>text</u> for underlined text.
The important part of this is, "Normally, this won't work because the String.format(String, Object...)method will strip all the style information from the string. The work-around to this is to write the HTML tags with escaped entities, which are then recovered with fromHtml(String), after the formatting takes place."
They say to "store your styled text resource as an HTML-escaped string" like
<string name="exit"><i>exit</i></string>
and then use:
Resources res = getResources();
String text = String.format(res.getString(R.string.exit));
CharSequence styledText = Html.fromHtml(text);
to get the formatted text correctly.
Did you just try to read your String into Spannable?
// Use a spannable to keep formatting
Spannable mySpannable = Html.fromHtml(context.getString(R.string.string_one));
textView.setText(mySpannable);

Getting force close when wanting to change focus from one EditText to Another

This is for my Android App. I have two EditText fields set to a maximum of one character that can be input in each field. Once the user inputs the first character I would like the focus to automatically jump to the second EditText field. I set up an addTextChangedListener on the first Edit Text and had it listen for when the text string is > 1. Then I call request focus on the second Edit Text. However, I keep receiving a force close when I input the character in the first Edit Text box. From what I've looked on StackOverflow, this should work. Anyone have any idea why it is not? I posted the relevant code below. Thanks.
LinearLayout llview = new LinearLayout(this);
llview.setOrientation(LinearLayout.VERTICAL);
EditText character1 = new EditText(this);
EditText character2 = new EditText(this);
character2.setId(2);
character1.addTextChangedListener(new TextWatcher(){
EditText character2 = (EditText) findViewById(2);
#Override
public void afterTextChanged(Editable s) {
if(s.length()>0)
{
character2.requestFocus();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,int after){}
#Override
public void onTextChanged(CharSequence s, int start, int before,int count) {}
});
llview.addView(character1);
llview.addView(character2);
this.setContentView(llview);
I'm not sure that you've posted all of the relevant code. It would seem that you are building your view hierarchy programmatically (rather than using a layout file), yet there is no code showing where you insert character1 and character2 into the view hierarchy. It would be helpful if you posted the code for building your view hierarchy.
Also, what debugging steps have you attempted so far? Have you set breakpoints to confirm that your variables are not null pointers when you invoke methods on them? Have you done a stack trace?
If I was to guess just based on this code segment you posted, then I would have to guess that you haven't inserted character1 and character2 into your activity's view hierarchy and findViewById(2) is simply returning null. Have you checked to see that findViewById(2) is in fact returning something other than null?

Categories

Resources