0

I'm developing a listview with photos and below this photo I have 1 normal button and 1 toggle button. I want this toggle button to act like a Like button - where if I tap one i increment the current number of likes of the photo and if i hit once again the button I decrement the no of likes.

Here's the code for this:

private View.OnClickListener likeBtnClickListener = new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            if(likeBtn.isChecked())
            {
                likeBtn.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.heart));
                likeBtn.setChecked(false);
                if(Integer.parseInt(likeBtn.getTextOff().toString())>0)
                {
                    likeBtn.setTextOff(String.valueOf(Integer.parseInt(likeBtn.getTextOn().toString())-1));
                }
                Log.e(String.valueOf(view.getTag()), "isChecked");
            }
            else
            {
                likeBtn.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.heart_on));
                likeBtn.setChecked(true);
                likeBtn.setTextOn(String.valueOf(Integer.parseInt(likeBtn.getTextOff().toString())+1));
                Log.e(String.valueOf(view.getTag()), "!!isChecked");
            }
        }
    };

And here's the getView method from my adapter:

public View getView(int position, View convertView, ViewGroup parent)
    {
        View view = convertView;

        if(view == null)
        {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.photo_view_cell, null);
        }

        Photo dData = data.get(position);
        if(dData!=null)
        {
            ImageView profileImg = (ImageView) view.findViewById(R.id.profile_img);
            TextView username = (TextView) view.findViewById(R.id.name);
            ImageView photoImage = (ImageView) view.findViewById(R.id.image);
            TextView date = (TextView) view.findViewById(R.id.date);
            likeBtn = (ToggleButton) view.findViewById(R.id.likesBtn);
            ToggleButton commentBtn = (ToggleButton) view.findViewById(R.id.commentsBtn);

            int noLikes = dData.getNoLikes();
            if(noLikes>0)
            {
                likeBtn.setChecked(true);
                likeBtn.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.heart_on));
                likeBtn.setTextOn(String.valueOf(noLikes));
                likeBtn.setTextOff(String.valueOf(noLikes));
            }
            else
            {
                likeBtn.setChecked(false);
                likeBtn.setBackgroundDrawable(getContext().getResources().getDrawable(R.drawable.heart));
                likeBtn.setTextOff("0");
                likeBtn.setTextOn("0");

            }
            likeBtn.setOnClickListener(likeBtnClickListener);
            username.setText(dData.getUser().getUsername());
            photoImage.setImageBitmap(dData.getImage());
            date.setText(dData.getDate());
        }

        view.setTag(position);
        return view;
    }

Now the problem is that this toggle buttons don't work as they should. For example right now I have 3 photos inflated in the main list view - and below each photo I have 1 toggle button and one normal button. When I tap the toggle button below the second button - the toggle button below the first photo activates - and if I tap the toggle button below or sometimes non of this toggle buttons work.

Can you please tell me what I'm doing wrong?

Thanks!

Alin
  • 1,044
  • 6
  • 20
  • 42

1 Answers1

1

It looks like you have likeBtn set as a global variable, which is manipulated in both your getView() and onClickListener(). This means that as each row of your list is created, you lose your reference to the previous buttons in favor of the new one. When any button is clicked and the listener evoked, your logic will only happen for the last row created with getView(), not necessarily the row that was clicked.

To fix this, you can localize the scope of your reference to the likeBtn using the View parameter to the onClick() method. This parameter will always be the View that was clicked, in this case, your ToggleButton. In your getView(), instead of using the global likeBtn, change this line:

likeBtn = (ToggleButton) view.findViewById(R.id.likesBtn);

to one that creates a local variable:

ToggleButton likeBtn = (ToggleButton) view.findViewById(R.id.likesBtn);

Then, in your onClick(), create another local variable to type cast the parameter:

@Override
public void onClick(View view)
{
    ToggleButton likeBtn = (ToggleButton) view;

    //Then the rest of your code
}
MattDavis
  • 5,158
  • 2
  • 23
  • 35