自定义arrayadapter和onclicklistener连续用于一个按钮 [英] Custom arrayadapter and onclicklistener for a button in a row

查看:102
本文介绍了自定义arrayadapter和onclicklistener连续用于一个按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的arrayadapter,我想在按钮的每一行中为按钮添加一个onclicklistener,当我单击该按钮时,我想更改图像资源,除了单击按钮时,一切正常图像更改,但另一行中另一个按钮的图像也更改.谢谢你的帮助 ! 这是我的代码:

I have a custom arrayadapter and I want to add an onclicklistener for a button in each one of its rows, when I click on the button I want the image resource to change, everything works fine except that when I click on a button the image changes but the image of another button in an other row also changes. Thanks for your help ! Here is my code:

    public class Coursadapter extends ArrayAdapter<String>{

    Context context; 
    int layoutResourceId;    
    ArrayList<String> data = null;
    WeatherHolder holder;

    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;

    }

    public View getView(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();
        }

        holder.b.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                WeatherHolder w = (WeatherHolder) v.getTag();
                w.b.setImageResource(R.drawable.butgreen);


            }
        });
        String name1 = data.get(position);
        holder.name.setText(name1);


        return row;
    }

    static class WeatherHolder
    {

        TextView name;
        ImageButton b;
    }
}

推荐答案

之所以发生这种情况,是因为适配器在滚动时回收了视图.

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

例如,假设您总共有15行,并且一次可以容纳5行. if(row == null)部分仅对前5行执行.向下滚动到第六行时,它将使用第一行的视图.这就是为什么您应该在if-else子句之后设置View的内容.因此,现在,当第六行进入屏幕时,该行不是null.它包含第一行的视图.当执行holder.name.setText(name1);时,它将第一行的名称替换为第六行的名称.同样,第七行使用第二行的视图,依此类推.

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.

现在,假设您单击第一行中的按钮.第一行的视图"更改,并且w.b.setImageResource(R.drawable.butgreen);设置第一行中按钮的图像资源.滚动到第六行时,它将使用第一行的视图.但是,您仅将holder.name设置为第六行的名称.第一行中按钮的图像资源将保留在那里,从而导致您的问题.

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.

解决方案:创建另一个ArrayList<String>并将按钮的状态存储在其中.因此,在您的情况下,我假设按钮的颜色为红色"或绿色".您可以在每个位置存储红色"或绿色",以表示每个按钮当前的颜色(可以将此ArrayList初始化为红色).然后,在加载每一行时,您可以设置图像资源以及该行的名称.看一下下面的代码.我在添加的行中添加了评论.

Solution: Create another ArrayList<String> 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;
}
}

这篇关于自定义arrayadapter和onclicklistener连续用于一个按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆