score:0

the problem with your code is that your onclicklistener is being set up in the wrong place.

consider what happens as a result of the if/else statement in getview(). if convertview passed into that method is null, it is likely the case that the view (and the listview containing it) is being created for the first time - for example, you are launching the activity that contains that listview. if it is not null, that means you are recycling a view that was, but is no longer, on-screen.

if you look carefully, you'll see that your onclicklistener only gets set in that first case - a brand new view. once you scroll around a bit, your listener will never be correctly attached to those views that are coming from off-screen.

a better getview() method would be:

public view getview(int position, view convertview, viewgroup parent) {
    view row = convertview;

    if (row == null) {
        layoutinflater inflater = ((activity) context).getlayoutinflater();
        row = inflater.inflate(layoutresourceid, null);

        holder = new weatherholder();
        holder.name = (textview) row.findviewbyid(r.id.item_cours_name);
        holder.b = (imagebutton) row.findviewbyid(r.id.button);

        row.settag(holder);

    } else {
        holder = (weatherholder) row.gettag();
    }

    string name1 = data.get(position);
    holder.name.settext(name1);

    holder.b.setonclicklistener(new onclicklistener() {
            @override
            public void onclick(view v) {                    
                ((imagebutton)v).setimageresource(r.drawable.butgreen);
            }
        });

    return row;
}

edit: added in the other fix from my below comment.

score:0

the reason why this happens is because the adapter recycles the views on scrolling.

for example, suppose you have a total of 15 rows and 5 rows fit on the screen at a time. the if(row == null) part executes for the first 5 rows only. when you scroll down to the 6th row, it uses the view of the 1st row. this is why you are supposed to set the content of your view after the if-else clause. so now, when the 6th row comes into the screen, row is not null. it holds the view of the 1st row. when it executes holder.name.settext(name1);, it is replacing the name of the 1st row with the name of the 6th row. similarly, the 7th row uses the view of the 2nd row and so on.

now, suppose you click on the button in the 1st row. the view for the 1st row changes and w.b.setimageresource(r.drawable.butgreen); sets the image resource of the button in the 1st row. when you scroll to the 6th row, it uses the view of the 1st row. but you are setting only holder.name to the name of the 6th row. the image resource of the button in the 1st row is going to remain there, hence causing your problem.

solution: create another arraylist and store the status of the button in this. so in your case, i'm assuming the buttons are either "red" or "green" in color. you could store either "red" or "green" at each position signifying what color each button is currently (you can initialize this arraylist to red). then, when each row loads, you can set the image resource along with the name of that row. take a look at the code below. i have put comments to the lines i added.

public class coursadapter extends arrayadapter<string> {

context context;
int layoutresourceid;
arraylist<string> data = null;
weatherholder holder;
arraylist<string> colors; // stores the color of each button

public coursadapter(context context, int layoutresourceid, arraylist<string> data) {
    // super(context, layoutresourceid, data, coeff);
    super(context, layoutresourceid, data);
    this.layoutresourceid = layoutresourceid;
    this.context = context;
    this.data = data;
    this.colors = new arraylist<>(collections.ncopies(data.size(), "red")); // initialize all the buttons to red color
}

public view getview(final int position, view convertview, viewgroup parent) {
    view row = convertview;


    if(row == null)
    {
        layoutinflater inflater = ((activity)context).getlayoutinflater();
        row = inflater.inflate(layoutresourceid, parent, false);

        holder = new weatherholder();
        holder.name = (textview)row.findviewbyid(r.id.item_cours_name);
        holder.b=(imagebutton) row.findviewbyid(r.id.button);
        holder.b.settag(holder);
        row.settag(holder);
    }
    else
    {
        holder = (weatherholder)row.gettag();
    }

    if(colors.get(position).equals("red")) {
        holder.b.setimageresource(r.drawable.butred); // set the colors of the button to red or whatever you need
    } else {
        holder.b.setimageresource(r.drawable.butgreen); // set the colors of the button to green
    }

    holder.b.setonclicklistener(new view.onclicklistener() {

        @override
        public void onclick(view v) {
            // todo auto-generated method stub
            weatherholder w = (weatherholder) v.gettag();
            //w.b.setimageresource(r.drawable.butgreen);
            colors.set(position, "green"); // update the arraylist colors
        }
    });
    string name1 = data.get(position);
    holder.name.settext(name1);


    return row;
}

static class weatherholder
{

    textview name;
    imagebutton b;
}
}

score:1

you can declare variable int that will hold the position of selected item and

public void onitemclick(adapterview<?> adapter, view arg1, int position, long id) {
            mselecteditem = position;
            madapter.notifydatasetchanged();
    }

and in your custom adapter getview method check the position and change the image of your button

public view getview(int position, view convertview, viewgroup parent) {
        if (position == mselecteditem) {
        // set your image
    }

look i try this code with me and work , implements onclicklistener in your activity

public class mainactivity extends activity  implements onclicklistener

and in your getview method

public view getview(int position, view convertview, viewgroup parent) {
        view row = convertview;

        if (row == null) {
            layoutinflater inflater = ((activity) context)
                    .getlayoutinflater();
            row = inflater.inflate(layoutresourceid, null);

            holder = new weatherholder();
            holder.name = (textview) row.findviewbyid(r.id.item_cours_name);
            holder.b = (imagebutton) row.findviewbyid(r.id.button);
            holder.b.setonclicklistener(mainactivity.this);

and the implement the onclick method set the resource

@override
public void onclick(view v) {
    weatherholder w = (weatherholder) v.gettag();
    w.b.setimageresource(android.r.drawable.star_big_on);
}

Related Query

More Query from same tag