ListView中的复选框在没有任何逻辑的情况下不断更改活动恢复的值

时间:2014-02-10 16:53:41

标签: android listview checkbox

我有一个使用自定义游标适配器的ListActvity。在每一行我都有一个复选框。当我点击一行时,另一个活动开始。如果我单击该复选框,则必须选中该复选框,并且不必开始任何活动。

所有这一切都有效。

但是发生了以下情况:如果我选择了一些复选框,然后单击一行,等待新活动,然后单击后退按钮返回ListActivity,复选框将恢复其状态而不带任何逻辑。被检查的人现在未经检查,未经检查的人未被检查......显然是随机的。

这是我正在使用的CursorAdapter类(最后我尝试恢复正确的复选框值):

public class EmailCursorAdapter extends SimpleCursorAdapter {

    Context context;
    LayoutInflater inflater;
    String[] from;
    int[] to;

    private static final String DATE_FORMAT = "dd-MM-yyyy HH:mm";
    private SimpleDateFormat sdf = new SimpleDateFormat(this.DATE_FORMAT, Locale.ITALY);

    public EmailCursorAdapter(Context context, int layout, Cursor c,
            String[] from, int[] to) {
        super(context, layout, c, from, to);

        this.context=context;
        this.from = from;
        this.to = to;

        this.inflater = LayoutInflater.from(context);

    }

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

        Cursor c = this.getCursor();

        c.moveToPosition(position);

        ViewHolder vh;

        if(v == null) {
            v = this.inflater.inflate(R.layout.email_adapter_row, parent, false);

            vh = new ViewHolder();

            v.setTag(vh);
        }
        else {
            vh = (ViewHolder) v.getTag();
        }

        vh.position = position;
        vh.database_id = c.getInt(c.getColumnIndex(MailDBHelper.MAIL_ID));

        if (this.from.length == this.to.length) {
            int i, size = this.from.length;
            for (i = 0; i < size; i++) {
                TextView tv = (TextView)v.findViewById(this.to[i]);

                if (this.from[i].equals(MailDBHelper.MAIL_DATE)) {
                    Timestamp tm = new Timestamp(c.getLong(c.getColumnIndex(MailDBHelper.MAIL_DATE)));
                    String s = this.sdf.format(new Date(tm.getTime()));
                    tv.setText(s);
                }
                else {
                    tv.setText(c.getString(c.getColumnIndex(this.from[i])));
                }
            }
        }

        int unseen = c.getInt(c.getColumnIndex(MailDBHelper.MAIL_NEW));
        View box = v.findViewById(R.id.email_row_box);
        if (unseen == MailDBHelper.MAIL_READ) { 
            box.setBackgroundColor(this.context.getResources().getColor(R.color.seen_email_background));
        }
        else {
            box.setBackgroundColor(this.context.getResources().getColor(R.color.white));
        }


        //////////////////////////////////////////
        // HERE I TRY TO RESTORE THE RIGHT VALUE
        //////////////////////////////////////////
        CheckBox cb = (CheckBox) v.findViewById(R.id.email_row_check);

        cb.setChecked(vh.isChecked);

        Log.d("DEBUG", "checkbox at position " + position +" is " + cb.isChecked());

        return v;
    }

    public class ViewHolder {
        public int database_id;
        public int position;
        public boolean isChecked;
    }

}

我正在使用ViewHolder类来跟踪复选框的当前状态。这是我的活动的onListItemClick()方法:

protected void onListItemClick (ListView l, View v, int position, long id) {
        ViewHolder vh = (ViewHolder)v.getTag();
        int email_id = vh.database_id;

        CheckBox cb = (CheckBox) v.findViewById(R.id.email_row_check);
        vh.isChecked = cb.isChecked();

        if (vh.isChecked) {
            Log.d("DEBUG", "checkbox at position " + vh.position + " is checked: true");
        }
        else {
            Log.d("DEBUG", "checkbox at position " + vh.position + " is checked: false");
        }

        this.read_email.putExtra("email_id", email_id);
        this.startActivity(this.read_email);
    }

从这个方法的日志中,它似乎需要正确的位置和正确的复选框值,并将其存储在右侧ViewHolder中。

修改

根据Rashmi的回答修改了getView()方法。

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

            Cursor c = this.getCursor();

            c.moveToPosition(position);

            ViewHolder vh;

            if(v == null) {
                v = this.inflater.inflate(R.layout.email_adapter_row, parent, false);

                vh = new ViewHolder();

                vh.cb = (CheckBox)v.findViewById(R.id.email_row_check);
                vh.cb.setOnCheckedChangeListener(ShowEmails.this);

                v.setTag(vh);
            }
            else {
                vh = (ViewHolder) v.getTag();
            }

            vh.position = position;
            vh.database_id = c.getInt(c.getColumnIndex(MailDBHelper.MAIL_ID));

            if (this.from.length == this.to.length) {
                int i, size = this.from.length;
                for (i = 0; i < size; i++) {
                    TextView tv = (TextView)v.findViewById(this.to[i]);

                    if (this.from[i].equals(MailDBHelper.MAIL_DATE)) {
                        Timestamp tm = new Timestamp(c.getLong(c.getColumnIndex(MailDBHelper.MAIL_DATE)));
                        String s = this.sdf.format(new Date(tm.getTime()));
                        tv.setText(s);
                    }
                    else {
                        tv.setText(c.getString(c.getColumnIndex(this.from[i])));
                    }
                }
            }

            int unseen = c.getInt(c.getColumnIndex(MailDBHelper.MAIL_NEW));
            View box = v.findViewById(R.id.email_row_box);
            if (unseen == MailDBHelper.MAIL_READ) { 
                box.setBackgroundColor(this.context.getResources().getColor(R.color.seen_email_background));
            }
            else {
                box.setBackgroundColor(this.context.getResources().getColor(R.color.white));
            }

            return v;
        }

与复选框关联的OnCheckedChangeListener在主要活动类中实现,它是:

@Override
    public void onCheckedChanged(CompoundButton btn, boolean isChecked) {
        ViewHolder vh = (ViewHolder)((View)btn.getParent()).getTag();

        vh.cb.setChecked(isChecked);
    }

现在,行为是不同的:只要我点击列表项,复选框就会随机重新排列,新活动开始,当我回来时,它们会回到正确的位置。这个代码是错的还是问题可能在其他地方?

1 个答案:

答案 0 :(得分:0)

除了查看器模式之外,您还需要一些额外的东西来使复选框适配器工作。

我正在为您提供如何解决此问题的伪代码

public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub

        View view = convertView;

        if (convertView == null) {

            layoutInflater = (LayoutInflater) mContext
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = layoutInflater.inflate(R.layout.cuisine_grid_item, parent,false);
            holder = new ViewHolder();
            holder.chkCuisine = (CheckBox) view.findViewById(R.id.chkMenu);
            view.setTag(holder);

            holder.chkCuisine.setOnCheckedChangeListener(new OnCheckedChangeListener() {

                @Override
                public void onCheckedChanged(CompoundButton btn, boolean val) {
                    // TODO Auto-generated method stub


                    int checkedItem = (Integer) btn.getTag();
                    cuisineList.get(checkedItem).setChecked(val);
                }
            });


        } else {

            holder = (ViewHolder) view.getTag();
        }

        Cuisine cuisine = cuisineList.get(position);
        holder.chkCuisine.setText(cuisine.getCuisineName());
        holder.chkCuisine.setTag(position);
        holder.chkCuisine.setChecked(cuisine.isChecked());
        return view;
    }