anonymous
anonymous

Reputation: 1330

setOnClickListener dynamically

I create different buttons dynamically like this:

for (int toShow = 1; toShow <= nShips; toShow++)
    {
        btn = new Button(this);
        btn.setBackgroundResource(shipDrawable.get(ima));
        btn.setLayoutParams(params);
        row[pos].addView(btn);
        btn.setId(shipId.get(ima));
        if (row[pos].getChildCount() == 3) pos++;
        ima++;
    }

I need to know the identity of each button because each other has different actions. Then, I try to set onClickListener like this:

btn.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View btn) {
            switch(btn.getId()){
                case 1000: System.out.println("FIRST");
                break;

                case 1004: System.out.println("FOURTH");
                break;
            }
        }
    });

But it doesn't work. It seems that the onClickListener only affects the last item was created. If I create four buttons, only the fourth will has an onClickListener.

How can I get my click listeners to work?

Upvotes: 3

Views: 5187

Answers (4)

Hiral Vadodaria
Hiral Vadodaria

Reputation: 19250

You can do like:

OnClickListener clicks=new OnClickListener() {

    @Override
    public void onClick(View v) {

            switch(v.getId())
            {
                case 1000: System.out.println("FIRST");
                break;

                case 1004: System.out.println("FOURTH");
                break; 
            }       
    }
};
for (int toShow = 1; toShow <= nShips; toShow++)
{
        btn = new Button(this);
        btn.setBackgroundResource(shipDrawable.get(ima));
        btn.setLayoutParams(params);
        row[pos].addView(btn);
        btn.setId(shipId.get(ima));
        btn.setOnClickListener(clicks);
        if (row[pos].getChildCount() == 3) pos++;
        ima++;
}

Upvotes: 5

TrungNguyen
TrungNguyen

Reputation: 185

                  for (Answer a : q.getAnswers()) {
                        final CheckBox cb = new CheckBox(this);
                        cb.setId(Integer.valueOf(a.getId()));
                        cb.setText(a.getValue());
                        cb.setTextColor(fontColor);
                        cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                            @Override
                            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                // TODO Auto-generated method stub
                                if(isChecked){
                                    inviCheckox.append("-"+String.valueOf(buttonView.getId()));
                                }

                        });
                        lCheckList.addView(cb);
                    }

I have tried with the code like this and it's working ( API Lv 10).

I can init the new View inside of the loop (final) and just add new listener to it

Upvotes: 0

YuviDroid
YuviDroid

Reputation: 1546

You can do this:

OnClickListener listener = new OnClickListener() {
            @Override
            public void onClick(View btn) {
                switch(btn.getId()){
                    case 1000: System.out.println("FIRST");
                    break;

                    case 1004: System.out.println("FOURTH");
                    break;
                }
            }
        };

for (int toShow = 1; toShow <= nShips; toShow++) {
        btn = new Button(this);

        // Set the click listener to all your buttons
        btn.setOnClickListener(listener);

        btn.setBackgroundResource(shipDrawable.get(ima));
        btn.setLayoutParams(params);
        row[pos].addView(btn);
        btn.setId(shipId.get(ima));
        if (row[pos].getChildCount() == 3) pos++;
        ima++;
    }

Cheers,
Yuvi

Upvotes: 3

Hossein
Hossein

Reputation: 4137

After the end of the for loop, btn refers to the last button created, not all of them. Each time you do btn = new Button(...) you lose the previous value of the btn.

Since you're setting the click listener outside the for loop, only the last button gets that handler. For all buttons to work, you need to set the listener inside the for loop.

And in such cases, instead of putting a switch in one function and set the listener of all objects to that function, you usually create a general function and set the click listener of each object to a delegate around that function that passes extra arguments to the general function to determine what should be done.

Upvotes: 3

Related Questions