0

In my app, I want a counter from 0 to 8 to decide the number of players in a game.

current design

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!)

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197

2 Answers2

0

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);
}
Moises
  • 56
  • 3
  • thank's mate, it worked perfectly! (to avoid the fatal exception I parsed the string of the counting field into an integer and the for loop is only executed if the amount is != 0 || in the range of 1-8). – Rainmaker Aug 13 '21 at 12:47
0

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!

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • thanks for the additional solution, I realized that I realize my goal by using @Moises-technique in combination with if statements instead of a for-loop (because I also have to disable visibilities when the minus button is clicked) – Rainmaker Aug 13 '21 at 13:16
  • You could just keep a ``playerCount`` variable, and when the user clicks plus or minus, update that variable and then call some ``update`` function. That function can just loop over the list and set the first ``playerCount`` items to visible, and the rest to invisible (you have to set them all to something, to be sure they're all in the correct state) – cactustictacs Aug 13 '21 at 16:58