带有查看器和复选框状态保存的 ListView

ListView with viewholder and checkbox state save

简单的购物清单应用程序。 ListView(带有自定义适配器的 TextView + CheckBox。试图实现 viewHolder 模式并完全丢失。我说得对吗?检查我的代码。还有如何保存复选框状态?我创建了大量,但不知道如何实现(滚动错误时取消选中)。

适配器:

public class ShopAdapter extends BaseAdapter {
private Context mainContex;
private ArrayList<ShopItem> shopItems;
boolean[] checkBoxState = new boolean[shopItems.size()];

static class ViewHolder {
    CheckBox checkBox;
    TextView textView;
}

public ShopAdapter(Context mainContex, ArrayList<ShopItem> shopItems) {
    this.mainContex = mainContex;
    this.shopItems = shopItems;
}

@Override
public int getCount() {
    return shopItems.size();
}

@Override
public Object getItem(int position) {
    return shopItems.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ShopItem shopItem = shopItems.get(position);
    View item = convertView;
    if (item == null) {

        item = LayoutInflater.from(mainContex).inflate(R.layout.shoplist_item, null);

        final ViewHolder viewHolder = new ViewHolder();
        viewHolder.textView = (TextView) item.findViewById(R.id.itemTextView);
        viewHolder.checkBox = (CheckBox) item.findViewById(R.id.doneCheckBox);
        viewHolder.textView.setText(shopItem.getDescription());
        viewHolder.checkBox.setChecked(shopItem.isDone());
        viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked) {
                    shopItem.setDone(true);
                    viewHolder.textView.setTextColor(mainContex.getResources()
                            .getColor(R.color.done_text_color));
                } else {
                    shopItem.setDone(false);
                    viewHolder.textView.setTextColor(mainContex.getResources()
                            .getColor(R.color.secondary_text));
                }
            }
        });
        item.setTag(viewHolder);
        viewHolder.checkBox.setTag(shopItems.get(position));
    } else {
        item = convertView;
        ((ViewHolder) item.getTag()).checkBox.setTag(shopItems.get(position));
    }
    ViewHolder holder = (ViewHolder) item.getTag();
    holder.textView.setText(shopItems.get(position).getDescription());
    holder.checkBox.setChecked(shopItems.get(position).isDone());
    return item;
}

}

项目:

public class ShopItem {

private String description;
private boolean done;

public String getDescription() {
    return description;
}

public void setDescription(String description) {
    this.description = description;
}

public boolean isDone() {
    return done;
}

public void setDone(boolean done) {
    this.done = done;
}

}

查看此实现: (对于您的复选框。即使在重新启动应用程序或只是滚动时,您是否想保留复选框状态?)

  // our ViewHolder.
 // caches our TextView
 static class ViewHolderItem {
 TextView textViewItem;
  }

getView()

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

ViewHolderItem viewHolder;

/*
 * The convertView argument is essentially a "ScrapView".
 * It will have a non-null value when ListView is asking you recycle the row layout. 
 * So, when convertView is not null, you should simply update its contents instead of inflating a new row layout.
 */
if(convertView==null){

    // inflate the layout
    LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
    convertView = inflater.inflate(layoutResourceId, parent, false);

    // well set up the ViewHolder
    viewHolder = new ViewHolderItem();
    viewHolder.textViewItem = (TextView) convertView.findViewById(R.id.textViewItem);

    // store the holder with the view.
    convertView.setTag(viewHolder);

}else{
    // we've just avoided calling findViewById() on resource everytime
    // just use the viewHolder
    viewHolder = (ViewHolderItem) convertView.getTag();
}

// object item based on the position
ObjectItem objectItem = data[position];

// assign values if the object is not null
if(objectItem != null) {
    // get the TextView from the ViewHolder and then set the text (item   name) and tag (item ID) values
    viewHolder.textViewItem.setText(objectItem.itemName);
    viewHolder.textViewItem.setTag(objectItem.itemId);
}

return convertView;

}

这是您的代码的正确实现-

    private static class ViewHolder {
                CheckBox checkBox;
                TextView textView;
            }

            public ShopAdapter(Context mainContex, ArrayList<ShopItem> shopItems) {
                this.mainContex = mainContex;
                this.shopItems = shopItems;
            }

            @Override
            public int getCount() {
                return shopItems.size();
            }

            @Override
            public Object getItem(int position) {
                return shopItems.get(position);
            }

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

            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                final ShopItem shopItem = shopItems.get(position);
                ViewHolder viewHolder;
            if (convertView == null) { 
                    viewHolder = new ViewHolder();

                    LayoutInflater layoutInflater = LayoutInflater.from(mContext);
                    convertView = layoutInflater.inflate(R.layout.shoplist_item, null);

                    viewHolder.textView = (TextView) item.findViewById(R.id.itemTextView);
                    viewHolder.checkBox = (CheckBox) item.findViewById(R.id.doneCheckBox);

            convertView.setTag(viewHolder);

        }
             else 
           {                
          viewHolder = (ViewHolder) convertView.getTag();
           }
viewHolder.checkBox.setTag(shopItems.get(position));
                    viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            if (isChecked) {
                                shopItem.setDone(true);
                                viewHolder.textView.setTextColor(mainContex.getResources()
                                        .getColor(R.color.done_text_color));
                            } else {
                                shopItem.setDone(false);
                                viewHolder.textView.setTextColor(mainContex.getResources()
                                        .getColor(R.color.secondary_text));
                            }
                        }
                    });




                viewHolder.textView.setText(shopItem.getDescription());
               viewHolder.checkBox.setChecked(shopItem.isDone());
                   return convertView;
            }

使用SparseBooleanArray

试试下面的代码

public class ShopAdapter extends BaseAdapter {
private Context mainContex;
private ArrayList<ShopItem> shopItems;
boolean[] checkBoxState = new boolean[shopItems.size()];
private SparseBooleanArray mSelectedItemsIds;

static class ViewHolder {
CheckBox checkBox;
TextView textView;
}

public ShopAdapter(Context mainContex, ArrayList<ShopItem> shopItems) {
this.mainContex = mainContex;
this.shopItems = shopItems;
mSelectedItemsIds = new SparseBooleanArray();
}

@Override
public int getCount() {
return shopItems.size();
}


 @Override
public Object getItem(int position) {
return shopItems.get(position);
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
final ShopItem shopItem = shopItems.get(position);
View item = convertView;
if (item == null) {

    item = LayoutInflater.from(mainContex).inflate(R.layout.shoplist_item, null);

    final ViewHolder viewHolder = new ViewHolder();
    viewHolder.textView = (TextView) item.findViewById(R.id.itemTextView);
    viewHolder.checkBox = (CheckBox) item.findViewById(R.id.doneCheckBox);

   if(mSelectedItemsIds.get(position)){
         shopItem.setDone(true);
         viewHolder.textView.setTextColor(mainContex.getResources().getColor(R.color.done_text_color));
    } else{
        shopItem.setDone(false);      
          viewHolder.textView.setTextColor(mainContex.getResources().getColor(R.color.secondary_text));
    }

    viewHolder.textView.setText(shopItem.getDescription());
    viewHolder.checkBox.setChecked(shopItem.isDone());
    viewHolder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (isChecked) {
                mSelectedItemsIds.put(position, value);
                shopItem.setDone(true);
                viewHolder.textView.setTextColor(mainContex.getResources()
                        .getColor(R.color.done_text_color));
            } else {
                mSelectedItemsIds.delete(position);
                shopItem.setDone(false);
                viewHolder.textView.setTextColor(mainContex.getResources()
                        .getColor(R.color.secondary_text));
            }
        }
    });
    item.setTag(viewHolder);
    viewHolder.checkBox.setTag(shopItems.get(position));
} else {
    item = convertView;
    ((ViewHolder) item.getTag()).checkBox.setTag(shopItems.get(position));
}
ViewHolder holder = (ViewHolder) item.getTag();
holder.textView.setText(shopItems.get(position).getDescription());
holder.checkBox.setChecked(shopItems.get(position).isDone());
return item;
}

}