Checkbox showing multiple time in grid view holder Pattern - android

i am showing and hiding checkbox on imageview click in gridview but when i click on one imageView checkbox appear on multiple image view android and as i scroll visible checkbox goes missing when i scroll
here is my Adapter
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ImageAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return arrPath.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(
R.layout.galleryitems, parent,false);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(R.id.itemCheckBox, holder.checkbox);
convertView.setTag(R.id.thumbImage,holder.imageview);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
holder.checkbox = (CheckBox)convertView.getTag();
holder.imageview = (ImageView)convertView.getTag();
}
holder.checkbox.setId(position);
holder.imageview.setId(position);
holder.checkbox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) v;
int id = cb.getId();
if (thumbnailsselection[id]) {
cb.setChecked(false);
thumbnailsselection[id] = false;
} else {
cb.setChecked(true);
thumbnailsselection[id] = true;
}
}
});
holder.imageview.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
ImageView iv = (ImageView )v;
int id = iv.getId();
if (holder.checkbox.getVisibility() == View.GONE) {
holder.checkbox.getTag();
holder.imageview.getTag();
holder.imageview.setAlpha(0.22f);
holder.checkbox.setVisibility(View.VISIBLE);
holder.checkbox.setChecked(true);
} else if (holder.checkbox.getVisibility() == View.VISIBLE) {
holder.imageview.setAlpha(0.8f);
holder.checkbox.setVisibility(View.GONE);
}
}
});
holder.checkbox.setTag(position);
holder.imageview.setImageBitmap(thumbnails[position]);
holder.checkbox.setChecked(thumbnailsselection[position]);
holder.id = position;
return convertView;
}
}
class ViewHolder {
ImageView imageview;
CheckBox checkbox;
int id;
}
}

try this code it worked for me,
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private ArrayList<Items> list
public ImageAdapter(ArrayList<Items> list) {
this.list=list;
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return list.size();
}
public Items getItem(int position) {
return list.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(
R.layout.galleryitems, parent,false);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
//Take image view in your XML
holder.checkbox = (ImageView) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(list.get(position).isImageSelected()){
// set your check image
holder.checkbox.setImageResource(checkResId);
}else{
// set your Uncheck image
holder.checkbox.setImageResource(unCheckResId);
}
holder.checkbox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if(list.get(position).isImageSelected()){
// set your Uncheck image
holder.checkbox.setImageResource(unCheckResId);
list.get(position).setIsImageSelected(false);
} else {
// set your check image
holder.checkbox.setImageResource(checkResId);
list.get(position).setIsImageSelected(false);
}
notifyDataSetChanged();
}
});
return convertView;
}
}
class ViewHolder {
ImageView imageview;
// Use ImageView for select and deselect
ImageView checkbox;
int id;
}
}
public class Items {
String thumbImageUrl;
boolean isImageSelected;
public String getThumbImageUrl() {
return thumbImageUrl;
}
public void setThumbImageUrl(String thumbImageUrl) {
this.thumbImageUrl = thumbImageUrl;
}
public boolean isImageSelected() {
return isImageSelected;
}
public void setIsImageSelected(boolean isImageSelected) {
this.isImageSelected = isImageSelected;
}
}

that's not how you use ViewHolder dude.
ViewHolder will also be reused like convertView as you set them as the tag.
It was supposed to link the UI, so that you don't need to call findViewById again.
But is your responsibility to maintain the data( the position of ImageView you selected in your case)
see this as an example.

Related

listview is not refreshing values after deleting row with checkbox value = true

Good day,
I'm doing a listview, baseadapter with checkbox that is able to delete multiple selected rows.
here is my onCreate :
ArrayList<Memos> list;
list = new ArrayList<Memos>();
list.add(new Memos(1, "s", "s"));
list.add(new Memos(2, "x", "aaa"));
list.add(new Memos(3, "v", "aesf"));
final ListView lv = (ListView) findViewById(R.id.myList);
lv.setAdapter(new MemoListAdapter(list, this));
deletebutton
#Override
public void onClick(View v) {
MemoListAdapter myAdapter = (MemoListAdapter)lv.getAdapter();
myAdapter.remove();
}
then here is my complete baseadapter :
public class MemoListAdapter extends BaseAdapter {
private List<Memos> listComment;
private Context context;
private LayoutInflater inflater = null;
private ArrayList<Memos> deleteMemos;
public MemoListAdapter(List<Memos> listComment, Context context) {
super();
this.listComment = listComment;
this.context = context;
inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
deleteMemos = new ArrayList<Memos>();
}
#Override
public int getCount() {
return listComment.size();
}
#Override
public Memos getItem(int position) {
return listComment.get(position);
}
#Override
public long getItemId(int arg0) {
return 0;
}
#Override
public int getViewTypeCount() {
return getCount();
}
#Override
public int getItemViewType(int position) {
return position;
}
public class ViewHolder
{
TextView body;
TextView date;
CheckBox checkBox;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_view, null);
holder = new ViewHolder();
holder.body = (TextView) convertView.findViewById(R.id.big_text);
holder.date = (TextView) convertView.findViewById(R.id.small_text);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
holder.body.setText(listComment.get(position).getMessageBody());
holder.date.setText(listComment.get(position).getMessageDate());
holder.checkBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//is chkIos checked?
if(listComment.get(position).isCheckbox()) {
holder.checkBox.setChecked(false);
deleteMemos.remove(listComment.get(position));
}
else {
// Do invisible or gone stuff here
holder.checkBox.setChecked(true);
deleteMemos.add(listComment.get(position));
}
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
public void remove() {
for(Memos memo : deleteMemos) {
listComment.remove(memo);
}
this.notifyDataSetChanged();
}
}
after selecting rows to delete (4 rows)
the list adjusted but the contents and the check value of the checkbox is still the same.
I am wondering what part of the notifyDataSetChanged is wrong.
Thanks in advance!
Your views are reused that's why it happen . Try adding below codes into your getView()
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_view, null);
holder = new ViewHolder();
holder.body = (TextView) convertView.findViewById(R.id.big_text);
holder.date = (TextView) convertView.findViewById(R.id.small_text);
holder.checkBox = (CheckBox) convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
if(listComment.get(position).isCheckbox()) {
holder.checkBox.setChecked(true);
}else {
holder.checkBox.setChecked(false);
}
holder.body.setText(listComment.get(position).getMessageBody());
holder.date.setText(listComment.get(position).getMessageDate());
holder.checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,boolean isChecked) {
listComment.get(position).setIsCheckbox(isChecked);
if (isChecked){
deleteMemos.add(listComment.get(position));
}else{
deleteMemos.remove(listComment.get(position));
}
}
});
return convertView;
}

Android : ImageView with checkbox in grid-view

I am trying to delete images with Checkbook.
I have done to delete the selected multiple images which is checked from grid-view on button click event. But the check-boxes are appearing as they are in the grid-view .
How can I remove the check-boxes also with images?
Thanks in advanced.
Here is my check-box code in getView() method in Android
class GridView_Adapter extends BaseAdapter {
private LayoutInflater mInflater;
SparseBooleanArray mSparseBooleanArray;
public GridView_Adapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSparseBooleanArray = new SparseBooleanArray();
}
public ArrayList<String> getCheckedItems() {
ArrayList<String> mTempArry = new ArrayList<String>();
for(int i=0;i<fileName.size();i++) {
if(mSparseBooleanArray.get(i)) {
mTempArry.add(fileName.get(i));
}}
return mTempArry;
}
public int getCount() {
return fileName.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.add_post_grid_item_layout, null);
holder.image = (ImageView) convertView.findViewById(R.id.image);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
Bitmap myBitmap = BitmapFactory.decodeFile(fileName.get(position));
holder.image.setImageBitmap(myBitmap);
final int pos = position;
holder.checkbox.setId(position);
holder.checkbox.setTag(position);
holder.checkbox.setChecked(mSparseBooleanArray.get(position));
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
{
mSparseBooleanArray.put((Integer) buttonView.getTag(), isChecked);
int pos = (Integer) buttonView.getTag();
if (!buttonView.isChecked())
{
picsName.remove((String) fileName.get(pos));
}
else if(buttonView.isChecked())
{
if (!picsName.contains((String) fileName.get(pos)))
{
picsName.add((String) fileName.get(pos));
}
}
notifyDataSetChanged();
}
});
return convertView;
}
class ViewHolder
{
ImageView image;
CheckBox checkbox;
int id;
}
}

How to use single selection checkbox in android?

public class ImageAdapter extends BaseAdapter
{
private LayoutInflater mInflater;
private Context mContext;
public ImageAdapter(Context context)
{
mContext = context;
}
public int getCount()
{
return count;
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
holder = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.state_info, null);
holder.textview = (TextView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.checkbox.setId(position);
holder.textview.setId(position);
holder.checkbox.setOnClickListener(new OnClickListener() {
public void onClick(View v)
{
// String h="hello";
CheckBox cb = (CheckBox) v;
int id = cb.getId();
if(cb.isChecked())
{
cb.setChecked(false);
}
Toast.makeText(Four.this, "Selected CheckBox ID" + v.getId(), Toast.LENGTH_SHORT).show();
}
});
holder.textview.setText(items.get(position).getName());
holder.checkbox.setChecked(thumbnailsselection[position]);
holder.id = position;
return convertView;
}
public void clear()
{
CheckBox cb=(CheckBox)findViewById(R.id.itemCheckBox);
// int id=cb.getId();
for(int j=0;j<count;j++)
{
cb.setChecked(false);
}
}
}
class ViewHolder
{
TextView textview , textIndexId;
CheckBox checkbox;
int id;
}
You can do one thing rather use checkbox you can use radon button but just change the style to check box
public class ImageAdapter extends BaseAdapter
{
private LayoutInflater mInflater;
private Context mContext;
public ImageAdapter(Context context)
{
mContext = context;
}
public int getCount()
{
return count;
}
public Object getItem(int position)
{
return position;
}
public long getItemId(int position)
{
return position;
}
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
convertView = LayoutInflater.from(mContext).inflate(R.layout.state_info, null);
holder = new ViewHolder();
holder.textview = (TextView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
convertView.setTag(holder);
//holder.checkbox.setId(position);
holder.textview.setId(position);
holder.checkbox.setId(position);
holder.checkbox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
for (int i = 0; i < count; i++)
{
if (v.getId() == i)
{
thumbnailsselection[i] = true;
Log.v("check", ""+position);
}
else
{
thumbnailsselection[i] = false;
}
}
notifyDataSetChanged();
}
});
if (thumbnailsselection[position])
{
holder.checkbox.setChecked(true);
}
else
{
holder.checkbox.setChecked(false);
}
holder.textview.setText(items.get(position).getName());
holder.checkbox.setChecked(thumbnailsselection[position]);
holder.id = position;
return convertView;
}
}

ListView Button positions repeating

Well i have a listview populated with BaseAdapter. In listview i have 2 textviews and 2 buttons that i want to be clickable and i did set it class and works fine but problem is when i click one textview, 4th, 8th list item below is clicked too and i just find out that they have same position by printing position with toast.
How can i make that positions go ++ and every of them be uniqe?
Adapter Class
public class CustomListAdapter extends BaseAdapter
{
private ArrayList<FeedItem> listData;
private LayoutInflater layoutInflater;
private Context mContext;
protected ListView feedListView;
public CustomListAdapter(Context context, ArrayList<FeedItem> listData)
{
this.listData = listData;
layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContext = context;
}
public void addItem(final FeedItem item) {
listData.add(item);
notifyDataSetChanged();
}
#Override
public int getCount()
{
return listData.size();
}
#Override
public Object getItem(int position)
{
return listData.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
public View getView( final int position, View convertView, ViewGroup parent)
{
final ViewHolder holder;
View row=convertView;
if (row == null)
{
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.headlineView = (TextView)convertView.findViewById(R.id.name);
holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
holder.approve = (TextView) convertView.findViewById(R.id.approveTV);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
FeedItem newsItem = (FeedItem) listData.get(position);
holder.approve.setFocusable(true);
holder.approve.setClickable(true);
holder.headlineView.setText(Html.fromHtml(newsItem.getTitle()));
holder.reportedDateView.setText(Html.fromHtml(newsItem.getContent()));
holder.approve.setTag(position);
holder.approve.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
Toast.makeText(mContext, String.valueOf(v.getTag()), Toast.LENGTH_LONG).show();
holder.approve.setTag(v);
holder.approve.setText("Approved");
}
});
return convertView;
}
static class ViewHolder
{
TextView approve;
TextView headlineView;
TextView reportedDateView;
ImageView imageView;
FeedItem newsItem;
}
}
Listview recycles views.
How ListView's recycling mechanism works
Change getView
public View getView( final int position, View convertView, ViewGroup parent)
{
ViewHolder holder;
if (convertView == null)
{
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.headlineView = (TextView)convertView.findViewById(R.id.name);
holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
holder.approve = (TextView) convertView.findViewById(R.id.approveTV);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
FeedItem newsItem = (FeedItem) listData.get(position);
holder.approve.setFocusable(true);
holder.approve.setClickable(true);
holder.headlineView.setText(Html.fromHtml(newsItem.getTitle()));
holder.reportedDateView.setText(Html.fromHtml(newsItem.getContent()));
holder.approve.setTag(position);
holder.approve.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
Toast.makeText(mContext, String.valueOf(v.getTag()), Toast.LENGTH_LONG).show();
}
});
return convertView;
}
As you are reusing the view by
else{
holder = (ViewHolder) convertView.getTag();
}
so multiple textView using same listener. So Take your onclickListener outside of the if condition.
if (convertView == null)
{
convertView = layoutInflater.inflate(R.layout.list_row_layout, null);
holder = new ViewHolder();
holder.headlineView = (TextView)convertView.findViewById(R.id.name);
holder.reportedDateView = (TextView) convertView.findViewById(R.id.confid);
holder.approve = (TextView) convertView.findViewById(R.id.approveTV);
convertView.setTag(holder);
}
else
{
holder = (ViewHolder) convertView.getTag();
}
holder.approve.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
Toast.makeText(mContext, String.valueOf(position), Toast.LENGTH_LONG).show();
}
});
Add this code in your list adapter :
#Override
public int getViewTypeCount() {
// TODO Auto-generated method stub
return questionsClassArrayList_.size();
}
#Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
return position;
}

Why does the sample code use getTag();

The following sample code is from website, I think holder = (ViewHolder) convertView.getTag() shoud be holder = (ViewHolder) convertView, right? Thanks!
public class ImageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
public ImageAdapter() {
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return count;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = mInflater.inflate(R.layout.galleryitem, null);
holder.imageview = (ImageView) convertView.findViewById(R.id.thumbImage);
holder.checkbox = (CheckBox) convertView.findViewById(R.id.itemCheckBox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.checkbox.setId(position);
holder.imageview.setId(position);
holder.checkbox.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
CheckBox cb = (CheckBox) v;
int id = cb.getId();
if (thumbnailsselection[id]) {
cb.setChecked(false);
thumbnailsselection[id] = false;
} else {
cb.setChecked(true);
thumbnailsselection[id] = true;
}
}
});
holder.imageview.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
int id = v.getId();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + arrPath[id]),
"image/*");
startActivity(intent);
}
});
holder.imageview.setImageBitmap(thumbnails[position]);
holder.checkbox.setChecked(thumbnailsselection[position]);
holder.id = position;
return convertView;
}
}
class ViewHolder {
ImageView imageview;
CheckBox checkbox;
int id;
}
}
I think holder = (ViewHolder) convertView.getTag() shoud be holder =
(ViewHolder) convertView,
since ViewHolder is not a View how could the cast works ? You set the ViewHolder object as tag for the convertView, and retrieve it everytime the getView is called, in order to avoid to look for your View components (your ImageView and CheckBox). This way you can avoid to call findViewById() during the scrolling of ListView.

Categories

Resources