简体   繁体   中英

Listview with button onclick's position changes while scrolling

I have a listview and it's scrolable. I have few listview items and it's pulled from database. My problem is, each listview items have a button and i've setOnclickListener to the button inside getView. Now let's say there's 5 items and i tap on button for item number 1, the position is 0 and when i scroll to the end of the list, i can see the button for item number 5 is clicked. When i scroll till middle of the list, sometimes the button randomly clicked and i can see from my logcat, the particullar button's position is 0. How come?

Here is my getView' code

public View getView(final int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.newsfeed_layout, parent, false);
        }
        final Button btnLike = (Button) v.findViewById(R.id.buttonLike);
        btnLike.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    String buttonText = btnLike.getText().toString();
                    if(buttonText.equals("LIKE")){
                        Toast.makeText(postedItems.this, "Liked This item" + position, Toast.LENGTH_SHORT).show();
                        btnLike.setPadding(4,0,12,0);
                        btnLike.setText("UNLIKE");
                        btnLike.setTextColor(Color.parseColor("#ffffff"));
                        btnLike.setBackgroundResource(R.drawable.likedredbutton);
                    }else if(buttonText.equals("UNLIKE")){
                        Toast.makeText(postedItems.this, "Unlike This Item" + position, Toast.LENGTH_SHORT).show();
                        btnLike.setPadding(4,0,20,0);
                        btnLike.setText("LIKE");
                        btnLike.setTextColor(Color.parseColor("#737373"));
                        btnLike.setBackgroundResource(R.drawable.cornerstyledbutton);
                    }
            }
        });
        return v;
    }

First, to understand the problem: this occurs because ListView reuses views as you scroll , to improve performance. That's the explanation for the convertView parameter.

Because of this, you need to make sure that whatever state you want to store for each item is stored in the adapter itself or wherever you store its backing data -- and that when you implement getView() , the UI is fully updated to reflect this data (since it will have whatever properties you set on it the last time it was used).

In this case, you need to store whether each item is "liked" or "unliked". And then, always set the properties of btnLike to reflect this before returning.

As an example, your code would have to be more or less like this:

public View getView(final int position, View convertView, ViewGroup parent)
{
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = ...;
    }

    final Button btnLike = (Button) v.findViewById(R.id.buttonLike);

    if (isLiked(position))
        setButtonAsUnlike(btnLike);
    else
        setButtonAsLike(btnLike);

    btnLike.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View v)
        {
            if (!isLiked(position))
            {
                // Not liked before, so like now.
                setLiked(position, true); // store this value.
                setButtonAsUnlike(btnLike); // the button is now "unlike"
            }
            else
            {
                // Liked before, unliked now.
                setLiked(position, false); // store this value.
                setButtonAsLike(btnLike); // the button is now "like"
            }
        }
    });

    return v;
}

where isLiked(position) queries the data, setLiked(position, boolean) updates it, and setButtonAsLike(Button) and setButtonAsUnlike(Button) update the visual properties of the Button as you are doing now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM