Пользовательский массив-адаптер и onclicklistener для кнопки в строке

1

У меня есть настраиваемый массив, и я хочу добавить onclicklistener для кнопки в каждой из своих строк, когда я нажимаю на кнопку, я хочу, чтобы ресурс изображения менялся, все работает отлично, за исключением того, что когда я нажимаю кнопку, изменяется изображение но изображение другой кнопки в другой строке также изменяется. Спасибо за вашу помощь ! Вот мой код:

    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;
    }
}
  • 1
    попробуйте переместить holder.b.setTag(holder); ниже остальной части. Ваша проблема в том, что lsitview повторяет представления.
  • 0
    Вы получили решение. Спасибо
Теги:
onclick
android-arrayadapter
custom-adapter
imagebutton

4 ответа

0

Причина, по которой это происходит, заключается в том, что адаптер перерабатывает представления при прокрутке.

Например, предположим, что у вас в общей сложности 15 рядов и 5 рядов, установленных на экране одновременно. Часть if(row == null) выполняется только для первых 5 строк. Когда вы прокручиваете до 6-й строки, она использует вид 1-й строки. Вот почему вы должны установить содержимое своего представления после предложения if-else. Итак, теперь, когда 6-я строка выходит на экран, строка не равна null. Он содержит вид 1-й строки. Когда он выполняет имя holder.name.setText(name1); , он заменяет имя первой строки именем 6-й строки. Аналогично, 7-я строка использует вид второй строки и так далее.

Теперь предположим, что вы нажимаете кнопку в 1-й строке. Вид для первой строки изменяется и wbsetImageResource(R.drawable.butgreen); устанавливает ресурс изображения кнопки в 1-й строке. Когда вы переходите к шестой строке, она использует вид 1-й строки. Но вы устанавливаете только имя holder.name имени 6-й строки. Ресурс изображения кнопки в 1-й строке останется там, что приведет к вашей проблеме.

Решение. Создайте еще один ArrayList<String> и сохраните статус кнопки в этом. Поэтому в вашем случае я предполагаю, что кнопки имеют либо "красный", либо "зеленый" цвет. Вы можете сохранить либо "красный", либо "зеленый" в каждой позиции, означающий, какой цвет каждой кнопки в данный момент (вы можете инициализировать этот ArrayList красным). Затем, когда каждая строка загружается, вы можете установить ресурс изображения вместе с именем этой строки. Взгляните на приведенный ниже код. Я добавил комментарии к строкам, которые я добавил.

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;
}
}
0

Существует общее недоразумение, которое разделяет ваш вопрос и оба ответа.

Прежде всего, убедитесь, что вы понимаете, как работает переработка ListView. Например, этот пост немного объясняет это.

Что касается этого конкретного случая, позвольте сначала понять проблему. Когда вы нажимаете на кнопку, изображение изменяется, и все выглядит нормально. Но если вы прокрутите список, вы получите тот же вид (с кнопкой с измененным изображением) в другой позиции. Из-за переработки.

Чтобы устранить эту проблему, вам необходимо сохранить выбор изображения на кнопке. Это не будет волшебным образом. Вы должны добавить некоторую логику, которая сообщает этому методу, какой ресурс изображения должен отображаться в определенной позиции.

Например, в вашем методе getView() добавьте следующий (псевдо) код:

public View getView(int position, View convertView, ViewGroup parent) {
    View row = convertView;
    if(row == null) {
        // omitted..
    }
    else {
        holder = (WeatherHolder)row.getTag();

        // BUTTON IMAGE MAINTAINING
        if(condition) {
           w.b.setImageResource(R.drawable.butgreen);
        } else {
           w.b.setImageResource(some-other-image-resource);
        }
    }

    // omitted..

    return row;
}
0

Немного сделано изменений, проверьте код

пакет com.example.dontpanic;

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.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);
                }
            });
            row.setTag(holder);

        } else {
            holder = (WeatherHolder) row.getTag();
        }

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

        return row;
    }

    static class WeatherHolder {

        TextView name;
        ImageButton b;
    }
}

поместите ваш прослушиватель кликов внутри, если условие и заданный тег за пределами условия if else

  • 0
    Извините, я обновил свой getview, как вы сказали, и у меня все та же проблема!
  • 0
    попробуйте отладить событие клика и проверить, что вы получаете. это может быть другая вещь
Показать ещё 4 комментария
0
public View getView(int position, View convertView, ViewGroup parent) {
    if(convertView == null)
    {
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
        convertView = inflater.inflate(layoutResourceId, parent, false);

    }
   TextView name = (TextView)convertView.findViewById(R.id.item_cours_name);
   ImageButton b=(ImageButton) convertView.findViewById(R.id.button);
   b.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
           b.setImageResource(R.drawable.butgreen);
        }
    });
    String name1 = data.get(position);
    name.setText(name1);
    return convertView;
}
  • 0
    это не сработало, я сделал, как вы сказали мне, и у меня все еще та же проблема
  • 0
    Просто замените метод getView на то, что я отредактировал. попробуй один раз
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню