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!

8 Answers 8

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);
   }
}
Sign up to request clarification or add additional context in comments.

3 Comments

"com.sample.project" can be replaced by getPackageName().
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.
Note that in my experience doing this gives you very poor performance.
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);
}

Comments

3

Take a look at these answers:

2 Comments

@user573536 be aware that using getResources().getIdentifier() in a loop can cause performance to degrade when you have a large number of lookups.
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).
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);

Comments

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());
            }
        }

Comments

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.

2 Comments

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().
No sorry no idea. A view knows his children, so I don't think it is too bad.
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);

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.