Флакторы не контролируются на прокрутке в пользовательском списке

StackOverflow https://stackoverflow.com/questions/9309250

Вопрос

Я знаю, что этот вопрос был задан снова и снова, но все же я не смог найти предложение, которое действительно помогает мне. Флажок не контролируется всякий раз, когда список прокручивается вниз. Да, я использую логический массив для хранения значений, но это все еще не решает проблему. Вот мой код. Пожалуйста, предложите решение для этого. Спасибо.

 public View getView(final int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
        final ViewHolder holder;
final boolean[] itemChecked=new boolean[30];

    LayoutInflater inflater =  context.getLayoutInflater();  
    if(convertView==null)  
    {  
        convertView = inflater.inflate(R.layout.custom_list, null);
        holder = new ViewHolder();  
        holder.txtViewTitle = (TextView) convertView.findViewById(R.id.title_text);  
        holder.txtViewDescription = (TextView) convertView.findViewById(R.id.description_text);  
        holder.cb=(CheckBox) convertView.findViewById(R.id.cb);
        convertView.setTag(holder);  

    }  

    else  
    {
        holder=(ViewHolder)convertView.getTag();  

     }  

    holder.cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                // TODO Auto-generated method stub
                 itemChecked[position] = isChecked;
                 if(itemChecked[position])
                 {
                     holder.cb.setChecked(true);
                 }
                 else
                 {
                     holder.cb.setChecked(false);
                 }
      holder.txtViewTitle.setText(title[position]);  
    holder.txtViewDescription.setText(description[position]);  
    holder.cb.setChecked(itemChecked[position]);
  holder.txtViewDescription.setFocusable(false);
  holder.txtViewTitle.setFocusable(false);

return convertView;  

}  

}
Это было полезно?

Решение

getView () вызывается всякий раз, когда необходимо нарисовать ранее невидимый элемент списка. Поскольку вы воссоздаете itemChecked[] Каждый раз, когда этот метод будет вызван, у вас будет новый флажок, и другой массив для каждого полученного представления. (Финал в Java не делает это поле уникальным, как в C) Самый простой способ решить это itemChecked Состояние флажки и восстановления и восстановления на основе этого.

public class MyListAdapter extends ArrayAdapter<Object> {
    private final boolean[] mCheckedState;
    private final Context mContext;

    public MyListAdapter(Context context, int resource, int textViewResourceId, List<Object> objects) {
        super(context, resource, textViewResourceId, objects);
        mCheckedState = new boolean[objects.size()];
        mContext = context;
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // simplified to just a Checkbox
        // ViewHolder and OnCheckedChangeListener stuff left out 
        CheckBox result = (CheckBox)convertView;
        if (result == null) {
            result = new CheckBox(mContext);
        }
        result.setChecked(mCheckedState[position]);
        return result;
    }
}

Другие советы

Вот пример. Прочитайте комментарии в GetView (...) адаптера, указанного ниже.


class TaskObject {
        private int pid;
        private String processName;
        private boolean toKill;
///getters/setters
        public boolean isToKill() {
            return toKill;
        }    
        public void setToKill(boolean toKill) {
            this.toKill = toKill;
        }
       ................................
    }

class TaskListAdapter extends BaseAdapter {

    private static final String TAG = "adapter";

    ArrayList<TaskObject> list;
    Context context;

    public TaskListAdapter(Context context) {
        Log.d(TAG, "created new task list adapter");
        this.context = context;
        if (list == null) {
            list = new ArrayList<TaskObject>();
        }
    }

    public void addTask(TaskObject taskObject) {
        list.add(taskObject);
    }

    public void clearTasks() {
        list.clear();
        Log.d(TAG, "list size:" + list.size());
        this.notifyDataSetChanged();
    }

    public int getCount() {
        return list.size();
    }

    public TaskObject getItem(int position) {
        return list.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(final int position, View convertView, ViewGroup parent) {        
        RelativeLayout rl = new RelativeLayout(context);
        TextView textPid = new TextView(context);
        textPid.setText(Integer.toString(getItem(position).getPid()));
        TextView textName = new TextView(context);
        textName.setText(getItem(position).getProcessName()); 

       /////Here is your and it will set back your checked item after scroll
         CheckBox chckKill = new CheckBox(context);
            if(getItem(position).isToKill())
            {
                    chckKill.setChecked(true);
            }
       ////////////////////////////////////////////////////////////////////           

            chckKill.setOnClickListener(new View.OnClickListener() {
              public void onClick(View v) {
                //is chkIos checked?
             if (((CheckBox) v).isChecked()) {
                 getItem(position).setToKill(true);
                }
              }
            });
            chckKill.setTag(getItem(position).getPid());
        /////////NOT LAYOUTED USE LAYOUT
            rl.addView(chckKill);
            rl.addView(textName);
            rl.addView(textPid);
            return rl;
        }    

Надеюсь, это поможет.

На Mycase я решил эту проблему следующим образом:

@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    ViewHolder holder = null;

    TextView title = null;
    ImageView thumbnail = null;
    CheckBox checkBox = null;

    Content rowData = GridViewActivity.contents.get(position);

    if (null == convertView) {
        convertView = mInflater.inflate(R.layout.grid_item, null);
        holder = new ViewHolder(convertView);
        convertView.setTag(holder);
    }
    holder = (ViewHolder) convertView.getTag();

    title = holder.getContentTitle();
    title.setText(rowData.getTitle());

    thumbnail = holder.getThumbnail();
    thumbnail.setImageResource(rowData.getIcon());

    checkBox = holder.getCheckBox();
    checkBox.setTag(position);

    checkBox.setChecked(rowData.isCheckBox());

    checkBox.setOnCheckedChangeListener(new OnCheckedChangeListener() {

        @Override
        public void onCheckedChanged(CompoundButton buttonView,
                boolean isChecked) {
            int getPosition = (Integer) buttonView.getTag();
            GridViewActivity.notifyCheckChanges(getPosition,
                    buttonView.isChecked());
        }
    });

    return convertView;
}

Вы должны разместить setChecked() после setOnCheckedChangeListener().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top