Android: Using findViewById() with a string / in a loop
Asked Answered
L

8

72

I'm making an android application, where there is a view composed of hundreds of buttons, each with a specific callback. Now, I'd like to set these callbacks using a loop, instead of having to write hundreds of lines of code (for each one of the buttons).

My question is: How can I use findViewById without statically having to type in each button id? Here is what I would like to do:

    for(int i=0; i<some_value; i++) {
       for(int j=0; j<some_other_value; j++) {
        String buttonID = "btn" + i + "-" + j;
        buttons[i][j] = ((Button) findViewById(R.id.buttonID));
        buttons[i][j].setOnClickListener(this);
       }
    }

Thanks in advance!

Lightner answered 1/2, 2011 at 16:35 Comment(0)
C
127

You should use getIdentifier()

for(int i=0; i<some_value; i++) {
   for(int j=0; j<some_other_value; j++) {
    String buttonID = "btn" + i + "-" + j;
    int resID = getResources().getIdentifier(buttonID, "id", getPackageName());
    buttons[i][j] = ((Button) findViewById(resID));
    buttons[i][j].setOnClickListener(this);
   }
}
Clueless answered 1/2, 2011 at 16:44 Comment(3)
"com.sample.project" can be replaced by getPackageName().Baucom
I'd seen other answers very similar to this, but the second arg being "id" was the last thing I needed for it to work.Hipped
Note that in my experience doing this gives you very poor performance.Kelson
A
6

You can try making an int[] that holds all of your button IDs, and then iterate over that:

int[] buttonIDs = new int[] {R.id.button1ID, R.id.button2ID, R.id.button3ID, ... }

for(int i=0; i<buttonIDs.length; i++) {
    Button b = (Button) findViewById(buttonIDs[i]);
    b.setOnClickListener(this);
}
Amah answered 1/2, 2011 at 16:39 Comment(0)
D
3

Take a look at these answers:

Dispatcher answered 1/2, 2011 at 16:40 Comment(2)
@Lightner be aware that using getResources().getIdentifier() in a loop can cause performance to degrade when you have a large number of lookups.Incoordination
You are right. I recommend that approach only when there's a sequence or order for the resources AND there are a lot of them (creating an array of 50 resources smells).Dispatcher
F
1

you can Use tag if you want to access.

in onClick

int i=Integer.parseInt(v.getTag);

But you cant access that button like this.

simply create button programatically

by Button b=new Button(this);

Francophile answered 1/2, 2011 at 16:42 Comment(0)
H
0

create Custom Button in java code rather in Xml as i shown below

Button bs_text[]= new Button[some_value];

    for(int z=0;z<some_value;z++)
        {
            try
            {

            bs_text[z]   =  (Button) new Button(this);

            }
            catch(ArrayIndexOutOfBoundsException e)
            {
                Log.d("ArrayIndexOutOfBoundsException",e.toString());
            }
        }
Himyarite answered 1/2, 2011 at 16:43 Comment(0)
C
0

If your top level view only has those button views as children, you could do

for (int i = 0 ; i < yourView.getChildCount(); i++) {
    Button b = (Button) yourView.getChildAt(i);
    b.setOnClickListener(xxxx);
}

If there are more views present you'd need to check if the selected one is one of your buttons.

Canister answered 1/2, 2011 at 16:55 Comment(2)
do you know how the performance compares with the other suggested methods? I'd assume that it was slightly slower than an array of ID's, but I'd be interested to know how it compares with getResources().getIdentifier().Incoordination
No sorry no idea. A view knows his children, so I don't think it is too bad.Canister
S
0

If for some reason you can't use the getIdentifier() function and/or you know the possible id's beforehand, you could use a switch.

int id = 0;

switch(name) {
    case "x":
        id = R.id.x;
        break;
    etc.etc.
}

String value = findViewById(id);
Shadrach answered 17/4, 2018 at 23:8 Comment(0)
V
0

To put it simply, here's a function for it

public View findViewByArrayName (String name, int i) {
        buttonID = name + Integer.toString(i);
        resID = getResources().getIdentifier(buttonID, "id", getPackageName());
        return findViewById(resID);
    }

Also unlike Python, Java is a compiled language, so it probably makes sense that there aren't any chances for dynamic variable names. Unless achieved through a certain approach like this one.

Vernal answered 22/6, 2021 at 16:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.