开发者

Is it possible to write a for loop to assign listeners to many button with the same function where final ints are used?

I am writing an android application and I have 8 buttons on one view that all have the same function, so I wanted to assign the same functionality to each button using a for loop rather than writing out 8 pieces of separate code. However, an issue arises when I want to use the the counter from the for loop within the onClick function to help fire an intent, here's the code:

//array of button ids
public int [] pickPlayers = { R.id.pick_player_1a, R.id.pick_player_2a, R.id.pick_player_3a, R.id.pick_player_4a, R.id.pick_player_1b, R.id.pick_player_2b, R.id.pick_player_3b, R.id.pick_player_4b};

//button to be 开发者_C百科used in for loop
public Button b;

//for loop to assign same functionality to buttons in pickPlayers array
for(int i = 0; i<pickPlayers.length; i++){
        b = (Button) findViewById(pickPlayers[i]);
        b.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent getContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
                startActivityForResult(getContactIntent, i);
            }
        });
    };

Hope that all makes sense, thanks to anyone who can help. :)

EDIT: This is the error I get: Cannot refer to a non-final variable i inside an inner class defined in a different method

The for loop is in my oncreate method the variables and buttons are outside


Yes you can't access variable in your inner classes if it's not declared as final. Simple workaround will be to create OnClickListener wrapper class.

private class MyListener implements Button.OnClickListener {
    int pos;
    public MyListener (int position) {
        pos = position;
    }
    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        Intent getContactIntent = new Intent(Intent.ACTION_PICK,ContactsContract.Contacts.CONTENT_URI);
        startActivityForResult(getContactIntent, pos);
    }
}

and then use it in you code like this

//for loop to assign same functionality to buttons in pickPlayers array
for(int i = 0; i<pickPlayers.length; i++){
    b = (Button) findViewById(pickPlayers[i]);
    b.setOnClickListener(new MyListener(i));
}

Also if your buttons are in some ViewGroup you can use getChildAt and getChildCount to iterate them

ViewGroup parent;
// initialize the parent
int l = parent.getChildCount();
for (int i = 0 ; i < l ; i++) {
    Button button = parent.getChildAt(i);
}


Just change your code like that:

//for loop to assign same functionality to buttons in pickPlayers array
for(int i = 0; i<pickPlayers.length; i++){
        final int index = i;
        b = (Button) findViewById(pickPlayers[i]);
        b.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                Intent getContactIntent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
                startActivityForResult(getContactIntent, index);
            }
        });
    };

This should do the job. Good luck!


If those buttons are decalred in XMl maybe you should set android:onClick listener to them through XML?

You have to define one method in your activity:

public void myHandler(View v) {
    // Your stuff...
}

And add

android:onClick="myHandler" 

to all of them?

Thanks.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜