0

I currently have a scrollview which I am adding rows to by inflating another xml layout. This is all working as it should and the row are all appearing correctly.

The issue I am having is that I am not sure how I can detect which button has been selected.

I have shown some example code for 1 on by buttons, simply put when this button is selected it toggles between 2 images. However, whenever I press the button it always automatially toggles the bottom rows button rather than the row in which the button has been selected.

Is there a way this can be implemented whilst still inflating a view to be used as a row (I do not want to dynamially create the rows, as this gets very messy)?

ScrollView scrollWeapons = (ScrollView)findViewById(R.id.scrollWeapons);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
int i = 0;

for(final Weapon w : Game.Weapons)
{
    View view = new View(this);
    LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    view = inflater.inflate(R.layout.menuweapons_row, null);

    btnSelected = (ImageButton)view.findViewById(R.id.btnSelected);
    btnSelected.setId(i);
    btnSelected.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            EquipUnequip(w.WeaponID());
        }
    });
}

private void EquipUnequip(int WeaponId)
{
    if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected)
    {
        btnSelected.setImageResource(R.drawable.eqip_but_idle);
    }
    else
    {
        btnSelected.setImageResource(R.drawable.eqip_but_press);
    }
}

ll.addView(view);
i++;
3
  • Is there any reason why you don't use a listview with a custom adapter for that? Commented Jun 11, 2014 at 13:29
  • I read that in general it is better to use a ScrollView Commented Jun 11, 2014 at 13:38
  • The opposide is correct if your data uses the same view: In a scrollview every view has to be created and hold in memory. Listviews recycle views. Commented Jun 11, 2014 at 13:44

2 Answers 2

1

The onClick method of OnClickListener has a parameter v. The value of v will be the View that was clicked, i.e. the ImageButton. All you have to do now is pass the View to EquipUnequip:

...
btnSelected.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        EquipUnequip(w.WeaponID(), (ImageButton)v);
    }
});
...

private void EquipUnequip(int WeaponId, ImageButton btnSelected) {
    if(Game.Weapons.get(WeaponId).CharacterID() == ChrSelected) {
        btnSelected.setImageResource(R.drawable.eqip_but_idle);
    } else {
        btnSelected.setImageResource(R.drawable.eqip_but_press);
    }
}

PS: This part seems a bit non-sensical to me:

View view = new View(this);
LayoutInflater inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.menuweapons_row, null);

Why do you create a new View just to do nothing with it and replace it with the result from the LayoutInflater?


Edit

If you really need the row of the View (and it never changes) here are 2 alternatives:

  1. Save row in the OnClickListener

    class MyOnClickListener implements OnClickListener {
        private final int rowIndex;
        MyOnClickListener(int rowIndex) {
            this.rowIndex = rowIndex;
        }
    
        @Override
        public void onClick(View v) {
            // do something with rowIndex
        }
    }
    

    and use it instead of your anonymus class or simply add a final variable outside your anonymus class:

    // currentRowIndex calculated by your program
    // i.e. incremented in every iteration
    final int rowIndex = currentRowIndex;
    btnSelected.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // do something with rowIndex
        }
    });
    
  2. Add the info as tag to the button (currentRowIndex would be of type int):

    btnSelected.setTag(currentRowIndex); // attach Integer data to the view
    btnSelected.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            int rowIndex = (Integer)v.getTag();
            // do something with rowIndex
        }
    });
    
Sign up to request clarification or add additional context in comments.

4 Comments

So stupid of me should have spotted that it works thanks
I do actually have one follow up question, I forgot that within my dynamic code i also have an ImageView, that when clicked need to act in the same way the ImageButton does. How can i possibly detected the ImageButton row when seleteing the ImageView on the same row?
@LandLPartners: You can add a field to the Listener (non-anonymus class) or add a final variable in the loop (so that it can be accessed from the anonymus listener class), use setTag + getTag of the View, ...
I have tried this before, but cannot quite get it to work could you provide some sample code?
1

Give the View parameter of onClick() to EquipUnequip(), cast this to ImageButton and use it. Otherwise you get the last created button.

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.