In my program I have dynamic buttons each representing a letter and I need to find a button that
has a specific letter. Since the buttons' text change from time to time, I cannot use findViewById method, instead i need a way of finding view by its text. Is there one?
If not, suppose the button that has the letter I am searching for has id = B12 and I can get the number 12 in my program. How do I convert number 12 into R.id.B12 ?
I think you are looking for "find resource by name" functionality
String mButtonName = "button" + 12;
int resID = getResources().getIdentifier(mButtonName , "id", getPackageName());
That's the way you get in int(id) from string, but you can do the same using reflection which is supposed to be way faster.
public static int getId(String resourceName, Class<?> c) {
try {
Field idField = c.getDeclaredField(resourceName);
return idField.getInt(idField);
} catch (Exception e) {
throw new RuntimeException("No resource ID found for: "
+ variableName + " / " + c, e);
}
}
And you use it like this:
getId("button" + 12, R.id.class);
Hope it Helps!
Regards!
Related
I have one sentence with 3 TextView in my RecyclerView. The picture is like below :
In that picture, I have one sentence in 3 TextView, there are "1" "HOT, MORE CHILLI" and "Pizza". This is my RecyclerView Binding code :
try {
view.txtArticlesName.setText(/*orderList.getJSONObject(position).getString("quantityValue") +*/
/*orderList.getJSONObject(position).getString("spesial-request").replaceAll("[\\\"\\[\\]]", "") + */
orderList.getJSONObject(position).getString("bezeich"));
view.txtQty.setText(orderList.getJSONObject(position).getString("quantityValue"));
view.txtReqList.setText(orderList.getJSONObject(position).getString("spesial-request").replaceAll("[\\\"\\[\\]]", ""));
} catch (JSONException e) {
e.printStackTrace();
}
I want to Join all of TextView with only one 'TextView` dynamicly. I'll try this :
view.txtArticlesName.setText(/*orderList.getJSONObject(position).getString("quantityValue") +*/
/*orderList.getJSONObject(position).getString("spesial-request").replaceAll("[\\\"\\[\\]]", "") + */
orderList.getJSONObject(position).getString("bezeich"));
But its not work, its not bind the data, so the TextView just show the default text "Hello World". Can TextView do this? I read about Spannable too but i dont know how its work to add new word in one TextView. Or there is another way to do this? Any suggest and answer will helpfull for me. Thanks before.
Simply concat the Strings in your TextView.
String string1 = "Hello", string2 = "HOT CHILLI", string3 = "PIZZA";
TextView textView = (TextView) findViewById(R.id.your_textView);
textView.setText(string1.concat(string2).concat(string3));
Or you could also append it to the existing TextView's text.
textView.setText(textView.getText().toString.concat(string2));
EDIT:
Collect the data from the server in String variables, and then pass those variables to the TextView.
String string1, string2, string3;
try {
string1 = orderList.getJSONObject(position).getString("quantityValue");
string2 = orderList.getJSONObject(position).getString("spesial-request").replaceAll("[\\\"\\[\\]]", "");
string3 = orderList.getJSONObject(position).getString("bezeich"));
String final = string1.concat(string2).concat(string3);
view.txtView.setText(final);
} catch (JSONException e) {
e.printStackTrace();
}
Use '+' operator or StringBuilder to join 2 or more strings and set the resultant string into a single textview.
If you want to have some part of text with different font, color, size, bold etc, you can use Spannable string or Html.fromHtml()
you can make and use spannable String like below :
private void addSpannableString(){
//"1" "HOT, MORE CHILLI" and "Pizza"
String one= "1";
String two= "HOT, MORE CHILLI";
String three= "Pizza";
String mergeString= one + two + three;
Spannable spannable = new SpannableString( mergeString );
StyleSpan boldSpan = new StyleSpan( Typeface.BOLD );
spannable.setSpan( boldSpan, mergeString.indexOf(two), mergeString.indexOf(three), Spannable.SPAN_INCLUSIVE_INCLUSIVE );
textview.setText(mergeString);
}
There are many methods are available to make Spans including colors and Typefaces
Use TextView.append(CharSequence text) to add more text to it.
Append the specified text to the TextView's display buffer, upgrading
it to BufferType.EDITABLE if it was not already editable
The Difference between GetString And OptString is:
From Documentation
OptString returns the empty string ("") if the key you specify doesn't
exist. GetString on the other hand throws a JSONException.
Use getString if it's an error for the data to be missing, or optString if you're not sure if it will be there.
I solved this with a little disappointed . Here my final code :
try {
view.txtArticlesName.setText(orderList.getJSONObject(position).getString("quantityValue") + " " +
orderList.getJSONObject(position).optString("spesial-request").replaceAll("[\\\"\\[\\]]", "") + " " +
orderList.getJSONObject(position).getString("bezeich"));
} catch (JSONException e) {
e.printStackTrace();
}
with getString :
with optString :
I change getString with optString and operator + work now. I'm not fully undertand why getString not work but optString work.
Thank you very much for all anwser, +1 from me
So first of all sorry if this has already been asked and answered before, I couldn't find anything relating to my issue.
So I'm working on a project for college and I need to get int values from EditText widgets. I was told to use parseInt to do this however when running my program, that line of code causes the application to crash. I don't know what I'm doing wrong, I'm still very new to android development, thanks for the help :)
public void Calculate (View view)
{
int MilesTravelled;
int FuelUsed;
int MPG;
/* the two lines below are what cause the application to crash */
MilesTravelled = Integer.parseInt(txtMilesTravelled.getText().toString());
FuelUsed = Integer.parseInt(txtFuelUsed.getText().toString());
FuelUsed = (int) (FuelUsed / 4.55);
MPG = MilesTravelled / FuelUsed;
lblMPG.setText(FuelUsed);
}
Do you have this in the onCreate() function?
EditText txtMilesTravelled = (EditText) findViewById(R.id.YourEditText);
But I think you mixed Integer and int. They are not the same:
See this link!
First of all, don't capitalize the first letter of an variables or method names. Following the Java coding conventions, only do that for classes.
What is probably causing your app to crash is you trying to set the text of a label to an integer. The setText method for a TextView needs to take in a string.
So change:
lblMPG.setText(FuelUsed);
to:
lblMPG.setText(String.valueOf(FuelUsed));
Otherwise it might be that it's trying to parse a non-numerical string to an integer.
For exmaple, if the EditText is blank, it will cause your app to crash. To prevent that, try this:
int MilesTravelled = 0, FuelUsed = 0;
try {
MilesTravelled = Integer.parseInt(txtMilesTravelled.getText().toString());
FuelUsed = Integer.parseInt(txtFuelUsed.getText().toString());
} catch (NumberFormatException nfe) {
Toast.makeText(getApplicationContext(), "Error NFE!", 0).show();
nfe.printStackTrace();
}
This way, it will catch a NumberFormatException error (parsing a string to an integer that can't be represented as an integer, such as "hello"). If it catches the error, it will toast that an error has occurred and your integer variables will remain 0.
Or you could just test if the strings contain only digits using the following regex:
int MilesTravelled = 0, FuelUsed = 0;
if (txtMilesTravelled.getText().toString().matches("[0-9]+")) {
MilesTravelled = Integer.parseInt(txtMilesTravelled.getText().toString());
} else {
// contains characters that are not digits
}
if (txtFuelUsed.getText().toString().matches("[0-9]+")) {
FuelUsed = Integer.parseInt(txtFuelUsed.getText().toString());
} else {
// contains characters that are not digits
}
If that's not the problem, then make sure you define your variables properly.
txtMilesTravelled and txtFuelUsed should be EditText:
EditText txtMilesTravelled = (EditText)findViewById(R.id.txtMilesTravelled);
EditText txtFuelUsed = (EditText)findViewById(R.id.txtFuelUsed);
And make sure that your R.id.editText actually exists on your layout and that the IDs are the correct ones.
Last thing, make sure FuelUsed is not 0 before calculating MPG because then you are dividing by 0:
int MPG = 0;
if (FuelUsed != 0) {
MPG = MilesTravelled / FuelUsed;
}
I am assuming that you're entering perfect integers in the EditTexts. It might be a good idea to use the trim function txtMilesTravelled.getText().toString().trim() before using parseInt.
However, I think the major problem is here : lblMPG.setText(FuelUsed);
FuelUsed is an integral value, when you pass an integer to setText(), it looks for a string resource with that integral value. So you should be passing a String to the setText() method.
Use : lblMPG.setText(Integer.toString(FuelUsed));
I am building an simple Android app am looking for a way to compare number input to a pre-stored integer. My first though was:
if(R.id.number == 123456){
}
This comparison does not work. I have also tried .equals, with no avail. Does anyone have any thoughts on how to compare the two values?
The R.id.number refers to a View's id (most likely an EditText since you say you are comparing user input). Thus, comparing that to a number would definitely not be what you're looking for. Find the EditText via findViewById(), parse its text into an integer and compare that.
Eg
public void onCreate (Bundle b){
super.onCreate (b);
EditText e = (EditText) findViewById (R.id.number);
int num = 0;
try{
num = Integer.parseInt (e.getText().toString().trim());
}
catch (NumberFormatException e){
}
if (num == 123456){
System.out.println ("Input equal");
}
}
I have just started to program in Android and I am still learning. I wanted to check if a year changes automatically when a nextMonth() method is used in case of December and January or whether I should change it with a few if statements. However, I canot display the value of that, instead I get an address. Here is my code:
TextView checkMonValue;
MonthDisplayHelper currentMonth = new MonthDisplayHelper(2012, 11);
MonthDisplayHelper nextMon = currentMonth;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkMonValue = (TextView)findViewById(R.id.monthValue);
checkMonValue.setText(String.valueOf(changeOfYear()));
}
public String changeOfYear(){
nextMon.nextMonth();
return nextMon + "" + nextMon.getYear();
}
And that is what get's displayed: Android.util.MonthDisplayHelper#44ee34e02013
Your are appending nextMon itself in your return value of changeOfYear() method. This way its returning the qualified name and address of nextMon as Android.util.MonthDisplayHelper#44ee34e0 appended with year as 2013.
Please correct to append nextMon.getMonth() and nextMon.getYear()
public String changeOfYear(){
nextMon.nextMonth();
return nextMon.getMonth() + "" + nextMon.getYear();
}
nextMon is an object as your return indicates. When you call nextMonth() you're issuing the command to increment the month but not actually retrieving anything.
Instead do this:
public String changeOfYear(){
nextMon.nextMonth();
return nextMon.getMonth() + " " + nextMon.getYear();
}
Note that I put a space in there where you only had "". You can even see this on your return: Android.util.MonthDisplayHelper#44ee34e02013
This is happening because nextMon is some type you defined, MonthDisplayHelper, and you haven't overridden the toString() method.
You can implement that method to return something meaningful, or, perhaps you meant to concatenate something different in this line:
return nextMon + "" + nextMon.getYear();
Probably something like this is what you want, nextMon.getMonth() or some method on nextMon.
I'm looking for a way to change the value of a string resource dynamically. I have tried to use reflection but it claims 'invalid value for field'.
I use the strings for values within the layout, but need to swap them out for different languages.
Please see the attached code below.
public class Lang{
public static void langInit(){
java.lang.reflect.Field[] langStringFields = R.string.class.getFields();
Log.d(Global.TAG,"--> Lang Listing: " + langStringFields.length);
Log.d(Global.TAG,"--> Pref for language:");
String prefInLang = Prefs.cPrefsGet.getString("in_lang","en");
String fieldName = null;
String fieldValue = null;
String newFieldName = null;
String tmpA = "one";
for (int i=0; i<langStringFields.length; i++){
java.lang.reflect.Field field = langStringFields[i];
fieldName = field.getName();
try {
fieldValue = Global.gActivity.getString(field.getInt(R.string.class));
} catch (Exception e) {
e.printStackTrace();
}
if (fieldName.substring(0,2).equals("lo")){
try {
newFieldName = R.string.class.getField(prefInLang + "_" + fieldName.substring(3)).getName();
} catch (Exception e) {
e.printStackTrace();
}
Log.d(Global.TAG,"--> Field: " + fieldName + "value: " + fieldValue + "new field:" + newFieldName);
try {
java.lang.reflect.Field field2 = Class.forName(R.string.class.getName()).getDeclaredField(newFieldName);
field2.setAccessible(true);
field2.set(R.string.class,tmpA.toString());
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Use built-in mechanism of localization, introduced in android. You don't need to change anything. You just need to specify the new strings.xml for each locale.
If you want to change current language for you app you can do it by using standard built-in localization features and changing locale programatically.
you should rather add a locale value to your resources and duplicate them : one for each language, thus letting the device choose the right one according to it's settings : check it there http://developer.android.com/resources/tutorials/localization/index.html
I believe using Android's built-in localization features is preferable to implementing it by hand. Here's a guide you can refer to:
http://developer.android.com/guide/topics/resources/localization.html
Unless, of course, we misunderstood your use case, but it does really sound like you are trying to do standard localization :-)
Bruno Oliveira, Developer Programs Engineer, Google