Change TextView value in a Fragment Class using Seekbar - java

I am using a Seekbar library so when I drag the seeker, I expect the textview to be updated with the value from the seeker but unfortunately my app crashes. I get an error that says, "resource not found on the TextView".
The code is below:
RangeSeekBar seekBar1;
seekBar1 = (RangeSeekBar)rootView.findViewById(R.id.seekBar);
seekBar1.setValue(10);
seekBar1.setOnRangeChangedListener(new RangeSeekBar.OnRangeChangedListener() {
#Override
public void onRangeChanged(RangeSeekBar view, float min, float max, boolean isFromUser) {
seekBar1.setProgressDescription((int)min+"%");
TextView txtAmount;
txtAmount = (TextView)rootView.findViewById(R.id.txtAmount);
txtAmount.setText((int) min);
}
});

Solution: You can't set int to the TextView like that, try this instead:
txtAmount.setText(Float.toString(min));
The overload you were using would look for a string resource identifier, that doesn't exist in this case. Here's the correct one that takes a CharSequence as an argument (string is a CharSequence).
Nice to know: If you're now left wondering how an int can be an argument to setText, it's quite simple. In your app, you can have a strings.xml file that defines a set of resources strings to be used in the application:
<resources>
<string name="test">This is a test</string>
</resources>
With that defined, you can show the text on your TextView like this:
txtAmount.setText(R.string.test);

If you pass an integer into setText, android expects the value to be a resource. The system is trying to find a resource who's id is equal to min. You need to convert min to a string.
So to get it working change txtAmount.setText((int) min); to txtAmount.setText(String.valueOf(min));

Related

How can I get and set a string resource dynamically in a for-loop using a findViewById() method?

In my app, I want a counter from 0 to 8 to decide the number of players in a game.
Below there are 8 possible fields to write a name inside, which are all set to invisible. If the players-counter is set to 3 players, there should be the first 3 fields visible. Depending on the actual number of the counter, the visibility of the fields changes (1player = first field, 5 players = first 5 fields).
When the +1 (player) button is clicked, a certain method is activated. I tried to run a for-loop everytime the button is clicked. In this for-loop from 0 to "whatever amount" (max. 8 players) the actual fields should be found with "findById" and set to visible.
I tried it with a string resource (.xml) and I can get the text of the resource but with my thought process, I have to update the string resource to every number of the field (if 3 players: "field_" + "1", "field_" + "2", "field_" + "3").
How can I get and (most importantly) set/update a string resource for this specific purpose?
(Switch is too inefficient and I can't use a string with the findViewBy Id()-method by updating the String (not string resource) like mentioned before.
Please help, and accept the fact that I'm new to Android Studio for one week!)
You can use "getIdentifier" which takes a String parameter. So you can set the type as "id" in the second parameter of this method. This method returns the id of the view you want, but beware, it will throw a "FATAL EXCEPTION" if the id of the View doesn't exist. With this id, you can use findViewById to fetch the TextView and change its visibility. The "getIdentifier" method can be called from the "getResources()" method.
Below you can see what it would be like to make visible a TextView that has the id "textView1":
int id = getResources().getIdentifier("textView1", "id", getPackageName());
TextView textView = findViewById(id);
textView.setVisibility(View.VISIBLE);
Below you can see how you would make 8 TextView with id 1 to 8 visible:
TextView textView;
for (int i = 1; i <= 8; i++) {
int id = getResources().getIdentifier("textView" + i, "id", getPackageName());
textView = findViewById(id);
textView.setVisibility(View.VISIBLE);
}
So, just put the limit at i <= x , with x being the limit of players who will play:
TextView textView;
for (int i = 1; i <= totalPlayers; i++) {
int id = getResources().getIdentifier("textView" + i, "id", getPackageName());
textView = findViewById(id);
textView.setVisibility(View.VISIBLE);
}
Do you just want to make some EditTexts visible and others not? Personally I'd keep it simple, do the lookups once (in onCreate or wherever) and store the references in a list. Then when you need to display n fields, you can just iterate over the list and set the first n to VISIBLE and the rest to INVISIBLE.
I feel like it's fine to just list all the EditText IDs (R.id.field_1 etc) and generate your list of actual Views from that, but if that repetition bothers you, there's a few things you could do. Like:
set a tag attribute on each field in the XML, and use findViewWithTag to look them up, generating the lookup strings programmatically, like "field_" + i
do a similar thing with the resource ID, like in #Moises's answer
lookup their containing layout, use getChildCount and [getChildAt] to iterate over the views in that layout, and use isInstance to collect all the EditTexts in order3
create and add the EditTexts in code - you probably don't want to do this, but you could!
I'm not really sure what you mean about the string resource or what you're trying to do - I'd honestly just make a list of R.id.field_1 etc, iterate over that to do findViewById on each and store those in a new list, and you're done. Also my Java's a bit rusty so sorry no example code!

Main Menu Buttons change colour but dont understand how

I have a main menu with buttons (days of the week). If data is stored in the database in reference to these days of the week then they will turn 'green'. I understand the SQL query itself but don't understand how colourChange function identifies each button and 'knows' how to change it. Can someone maybe explain how this works?
MainMenu.java
private void colourChange() {
Cursor result = myDb.checkColour();
if (result.getCount() == 0) { // If the result equals to 0 then do nothing.
// Default colour remains
} else {
// if the result is not 0 then...
while (result.moveToNext()) { // Move through each result...
String day = result.getString(0); // and store the day (column 0) of the result in day
findViewById(getResources().getIdentifier(day + "button", "id", getPackageName())) // Find the view by ID using getResources.getIdentifier and passing the following parameter (day)
.setBackgroundColor(getResources().getColor(R.color.colorSuccess)); // The variable colourSuccess stored in the colours.xml file sets the background colour green.
}
}
}
Database.java
public Cursor checkColour() { // a SELECT statement is used to SELECT DayOfWeek FROM RoutineTable and GROUP BY DayOfWeek and store this as result.
SQLiteDatabase db = this.getWritableDatabase();
Cursor result = db.rawQuery("SELECT DayOfWeek FROM " + RoutineTable + " GROUP BY DayOfWeek", null);
return result;
}
Let's break the code down.
getResources().getIdentifier(day + "button", "id", getPackageName())
The Resources.getIdentifier() method allows you to access the various constants inside R.java dynamically, by name. day + "button" is the name of the resource and "id" is the type of the resource. So this method will return R.id.[day]button. If day holds "sunday", then you're going to get R.id.sundaybutton.
findViewById( [code from above] )
Now that getIdentifier() has returned a "real" id to you (like R.id.sundaybutton), findViewById() will search your layout for a View object with that android:id attribute. So if your layout includes a View with android:id="#+id/sundaybutton", findViewById(R.id.sundaybutton) will return it.
getResources().getColor(R.color.colorSuccess)
Resources.getColor() takes a color identifier (here R.id.colorSuccess) and returns the color value (perhaps it is green, maybe 0xFF00FF00).
setBackgroundColor( [color from above] )
This one is easy: it sets the background color of the specified View.
Altogether, you're going to iterate over the days of the week and
build an identifier from the day of the week
find a view using that identifier
get a color value from your resources
apply that color value to the found view's background
Hope this helps!
Good afternoon,
Without seeing all of the code for the resource file information for the application it will be hard to give you a definite answer. Looking at the code it looks like it matches a resource with the day of the week returned in the query plus the word "button" in the current application. Then it sets the background color by looking in the color resource folder for a resource called "colorSuccess", which changes it to the color green.
That colourChange() function firstly requesting to database return as cursor.
while (result.moveToNext()) is looping while all rows of result.
getResources().getIdentifier(day + "button", "id", getPackageName())
That find resources by specified layout id.Example "#+id/fridaybutton"
Accoriding android api documents. function paramters is here.
getIdentifier(String name, String defType, String defPackage)

Java - dynamically build textview reference

New Android/Java coder. Trying to replicate in Android app a project I built in MS-Access.
I have a layout with similar named TextViews, like text10, text12, etc. In MS-Access I can dynamically build those names with collection referencing:
For X = 10 To 15
Me.Controls("text" & X) = Null
Next
There is no array required. So looking for structure in java that can accomplish the same functionality.
I want to dynamically set background color of multiple TextView based on two inputs. One is to build TextView reference and the other is a state indicator that will determine color.
Here is one procedure calling setSubColor:
public void Clear(MenuItem mi) {
puz.setText("");
sol.setText("");
for (int i=0; i<26; i++) {
setSubColor(aryA[i].charAt(0), 0);
What I have so far for setSubColor:
public void setSubColor (char c, int i) {
TextView v = (TextView) >>>dynamically reference v using name built with ("tv" + c)
if (i == 0) {v.setBackgroundColor(Color.TRANSPARENT);}
else {v.setBackgroundColor(Color.YELLOW);}
You can get the res id from the res name at runtime. So if your textview had name "text1", you could get the integer id by using:
int id = getResources().getIdentifier("text1", "string", getPackageName());
TextView view = findViewById(id);
But do so only as a last resort, it's error prone, slow and somewhat of an anti pattern.
EDIT by OP: No matter what the name argument is always returns 0 but marked as answer because it led to the following code that works exactly as I want, anti-pattern or not.
TextView v = (TextView) findViewById(getResources().getIdentifier("tv" + c, "id", getPackageName()));
Instead of the TextView Id field use its Tag field.
String tag = (String)textView.getTag() and textView.setTag(Object tag) with tag instanceof String
then you can find the TextView by Tag

ImageView setBackround inside the activity dynamically

Inside my drawabale folder I have these images: levelone, leveltwo, level three.
i need to set the ImageView according to the inputted string as follows:
levelindicatorImageView = (ImageView) findViewById(R.id.levelindicatorImageView);
String tempo="R.drawable.level"+LevelReached;
Drawable replacer = getResources().getDrawable(tempo);
int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < android.os.Build.VERSION_CODES.JELLY_BEAN) {
levelindicatorImageView.setBackgroundDrawable(replacer);
} else {
levelindicatorImageView.setBackground(replacer);
}
levelindicatorImageView.invalidate();
now inside LevelReached variable i have the needed level (one, two, three)
I need to set the Image R.drawable.leveltwo etc...
How is that possible please?
as getDrawable doesn't work with tempo (needs int)
thanks for the help!
You have 2 options:
Option 1:
Simply use a switch-case to get the correct drawable, then set it as a background image as you normally would
// Get the level drawable resource id
int imageRes = R.drawable.default_image;
switch (levelReached) {
case LEVEL_ONE: // 1
imageRes = R.drawable.level_one;
break;
case LEVEL_TWO: // 2
imageRes = R.drawable.level_two;
break;
...
}
// Set the drawable as a background
levelIndicatorImageView.setBackgroundResource(imageRes);
Where LEVEL_ONE == 1; LEVEL_TWO == 2; as const or enum.
Option 2:
You can find a drawable resource by name (as you wanted), but it is less recommended since it is more error prune. But if you must, use following example:
// Get the level drawable resource id
int imageRes = getResources().getIdentifier("level"+levelReached, "drawable", getPackageName());
// Set the drawable as a background
levelIndicatorImageView.setBackgroundResource(imageRes);
Note:
You don't need to explicitly invalidate the view if you set the background since setting a new background will trigger invalidation by itself. So, this line:
levelindicatorImageView.invalidate();
is not needed.
You cant append input string to image name, but what you can do is,
select the image based on input string and then If you have 3 different images, try with ;
if(input.equalsIgnoreCase("input one"))
{
int id = R.drawable.<img one>;
}
else
{
//so on
}
levelindicatorImageView.setBackground(getResources().getDrawable( id) );
You need to do something like this:
public int getResourecId(String level) {
if(level.equalsIgnoreCase("one"))
return R.drawable.levelone;
if(level.equalsIgnoreCase("two"))
return R.drawable.leveltwo;
if(level.equalsIgnoreCase("three"))
return R.drawable.levelthree;
return 0;
}
and then:
Drawable replacer = getResources().getDrawable(getResourceId(LevelReached));
You need to associate the levels to a resource, in this case, an int. An idiomatic way of doing this would be to store the levels as an enum, say
enum Level { ONE, TWO, THREE }
Using an enum in this way allows you some flexibility with your level conventions. For example, if you later wanted to add the level TWO_THIRDS, there is nothing stoping you. Then, associate each level with a resource in an EnumMap, for example:
Map<Level, Integer> levelResources = new EnumMap<Level, Integer>(Level.class);
levelResources.put(ONE, R.drawable.levelOne);
levelResources.put(TWO, R.drawable.levelTwo);
levelResources.put(THREE, R.drawable.levelThree);
Now, instead of passing around a string which describes your current level, you can pass around an enum, which you can use to determine the correct resource without concatenating strings. So, suppose that levelReached is of type Level, you could write:
Integer tempo = levelResources.get(levelReached);
Drawable replacer = getResources().getDrawable(tempo);

numbered images on setImageResource

I'm working on an Android App, and I had the following code:
int digit = 0;
imageButton = (ImageView)findViewById(R.id.btn1);
numberedImage = (ImageView)findViewById(R.id.Digit1);
imageButton.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
digit++;
numberedImage.setImageResource(R.drawable.number + ((digit) + 1));
}
});
and some images on a drawable folder called number1, number2, and so on...
This code was working perfectly, and then, suddenly, it's not working anymore.
I want the ImageView to change the images each click, and what made me completely confused, is the fact that this code was working completely fine (even though it might be wrong some way, I'm not a programmer), and all of the sudden, it's not anymore...
After that I also tried using arrays and loops, but I encountered the same error:
"number cannot be resolved or is not a field"
which wasn't a problem before.
You have some misunderstanding. But may be fortunately(or unfortunately) your code gave you some successful result for which your misunderstanding was more firmed.
ImageView.setImageResource takes a resource id as parameter. not a image name. so when you are adding a digit to the resource id it is setting the image of next id. as your images' names are sequential so the ids were also sequential that's why you got successful result. But it is not guranteed that you will always be getting that done.
I guess previously it was working because there was an image named number in your resource. But now it is removed.
Proposed solution
Resources res = getResources();
String mDrawableName = "number" + digit + 1; // be sure those exist
int resID = res.getIdentifier(mDrawableName , "drawable", getPackageName()); numberedImage.setImageResource(resId);
please kindly use
for(int i=0;i<imageCount;i++){
int imageResId = getResources().getIdentifier("image" + i, "id", YourActivity.this.getPackageName());
numberedImage.setImageResource(imageResId);
}
in order to access image by resource name.

Categories