Maintain the state of selected listview Imagebutton on scrolling - android

I try to implement add to favorites functionality in my app .I have two Image-buttons addToFavouritiesBtn and removeFromFavouritiesBtn in list-view . At a time only one Image-button get visible on selection.
My problem is , when I select addToFavouritiesBtn it gets selected , but when I scroll-down list-view and come back to that Image-button , it remains unselected.
Please tell me how to maintain state of the selected items on scrolling.
Here is my code.
public class Product{
private boolean selected = false;
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected) {
this.selected = selected;
}
}
ProdctListAdaptet.class
public class ProductListAdapter extends BaseAdapter {
private Activity activity;
private List<Product> productItems;
private Context context;
int pos;
int flag = 0 ;
public ProductListAdapter(Context context,Activity activity, List<Product> productItems,int flag) {
this.activity = activity;
this.productItems = productItems;
this.context = context;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// ProductHolder holder = null;
final ProductHolder holder;
if (convertView == null) {
holder = new ProductHolder();
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.product_list_row_item, parent,false);
holder.thumbNail = (ImageView) convertView
.findViewById(R.id.product_image);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.btnAddFavourite = (ImageButton) convertView.findViewById(R.id.AddFavourites);
holder.btnRemoveFavourite = (ImageButton) convertView.findViewById(R.id.RemoveFavourites);
holder.btnAddFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 1;
System.out.println("Add favourities");
pos = (Integer) v.getTag();
productItems.get(pos).setSelected(false);
holder.btnAddFavourite.setVisibility(View.GONE);
holder.btnRemoveFavourite.setVisibility(View.VISIBLE);
//notifyDataSetChanged();
}
});
holder.btnRemoveFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flag = 2;
System.out.println("Remove favorities");
pos = (Integer) v.getTag();
productItems.get(pos).setSelected(true);
holder.btnAddFavourite.setVisibility(View.VISIBLE);
holder.btnRemoveFavourite.setVisibility(View.GONE);
// notifyDataSetChanged();
}
});
convertView.setTag(holder);
} else {
holder = (ProductHolder) convertView.getTag();
}
holder.btnAddFavourite.setTag(position);
holder.btnRemoveFavourite.setTag(position);
Product state = productItems.get(position);
System.out.println("Product position -----> " + state);
if (state.isSelected()) {
System.out.println("Selected state ******************* " + state.isSelected());
System.out.println("selected");
holder.btnAddFavourite.setVisibility(View.VISIBLE);
holder.btnRemoveFavourite.setVisibility(View.GONE);
} else {
System.out.println("Selected state ******************* " + state.isSelected());
System.out.println(" not selected");
holder.btnAddFavourite.setVisibility(View.GONE);
holder.btnRemoveFavourite.setVisibility(View.VISIBLE);
}
convertView.setTag(holder);
return convertView;
}
final Product product = (Product) productItems.get(position);
//final Product product = (Product) getItem(position);
holder.thumbNail.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
holder.title.setText(product.getName());
Picasso.with(activity).load(product.getHref())
.placeholder(R.drawable.ic_default_banner)
.into(holder.thumbNail);
private class ProductHolder {
TextView title;
ImageView thumbNail;
ImageButton btnAddFavourite;
ImageButton btnRemoveFavourite;
}
}

you have to use youradapetr.notifydatasetchanged() after change in dataset in your button onclick function
, in your case simply add notifyDataSetChanged(); like below in both function
holder.btnAddFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Add favourities");
int pos = (Integer) v.getTag();
productItems.get(pos).setSelected(false);
holder.btnAddFavourite.setVisibility(View.GONE);
holder.btnRemoveFavourite.setVisibility(View.VISIBLE);
notifyDataSetChanged();
}
});

I think the problem is inside the onClickListener. Use position which is coming as parameters instead of pos for setting the state inside your listeners.
holder.btnAddFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Add favourities");
productItems.get(position).setSelected(false);
holder.btnAddFavourite.setVisibility(View.GONE);
holder.btnRemoveFavourite.setVisibility(View.VISIBLE);
}
});
holder.btnRemoveFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("Remove favorities");
productItems.get(position).setSelected(true);
holder.btnAddFavourite.setVisibility(View.VISIBLE);
holder.btnRemoveFavourite.setVisibility(View.GONE);
}
});
EDIT 1:-
Can your try below getView method. I think you are setting incorrect state in onclick listener. You are setting setSelected(true) in btnRemoveFavourite but it should be setSelected(false). Same applies for btnAddFavorite.
Please try below code and accept the answer if its correct.
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ProductHolder holder = null;
if (convertView == null) {
holder = new ProductHolder();
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.product_list_row_item, parent, false);
holder.thumbNail = (ImageView) convertView.findViewById(R.id.product_image);
holder.title = (TextView) convertView.findViewById(R.id.title);
holder.btnAddFavourite = (ImageButton) convertView.findViewById(R.id.AddFavourites);
holder.btnRemoveFavourite = (ImageButton) convertView.findViewById(R.id.RemoveFavourites);
convertView.setTag(holder);
} else {
holder = (ProductHolder) convertView.getTag();
}
final Product product = productItems.get(position);
holder.btnAddFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
product.setSelected(true);
holder.btnAddFavourite.setVisibility(View.GONE);
holder.btnRemoveFavourite.setVisibility(View.VISIBLE);
}
});
holder.btnRemoveFavourite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
product.setSelected(false);
holder.btnAddFavourite.setVisibility(View.VISIBLE);
holder.btnRemoveFavourite.setVisibility(View.GONE);
}
});
if (product.isSelected()) {
System.out.println("Selected state ******************* " + state.isSelected());
System.out.println("selected");
holder.btnAddFavourite.setVisibility(View.GONE);
holder.btnRemoveFavourite.setVisibility(View.VISIBLE);
} else {
System.out.println("Selected state ******************* " + state.isSelected());
System.out.println(" not selected");
holder.btnAddFavourite.setVisibility(View.VISIBLE);
holder.btnRemoveFavourite.setVisibility(View.GONE);
}
return convertView;
}

The Issue:
getView() in your adapter gets called from time to time. As a result, if the selected state is not set for the button, it will revert to the original state.
Solution:
Keep a boolean in the model class [Product] with getters and setters:
boolean didSelect;
public boolean isDidSelect() {
return didSelect;
}
public void setDidSelect(boolean didSelect) {
this.didSelect = didSelect;
}
In getView(), depending on the value in the boolean set the selection of the button.

Here i am giving a simple demo for you,You Can update it according your requirement,I hope you will get your Solution.
public class MainActivity extends Activity {
String s[] = { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
"M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",
"Z" };
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Product> products = new ArrayList<Product>();
ListView list = (ListView) findViewById(R.id.listview);
for (int i = 0; i < s.length; i++) {
Product item = new Product();
item.setCheck(false);
item.setName(s[i].toString());
products.add(item);
}
ProductListAdapter ac = new ProductListAdapter(MainActivity.this, R.layout.row,
products);
list.setAdapter(ac);
}// on create method end
class ProductListAdapter extends BaseAdapter {
private List<Product> productItems;
Context context;
int layoutId;
public ProductListAdapter(Context context, int layoudId, List<Product> productItems) {
// super(context,productItems);
this.layoutId = layoudId;
this.context = context;
this.productItems = productItems;
}
public class ProductHolder {
ImageView image;
TextView name;
}
#Override
public View getView(final int position, View convertView,
ViewGroup parent) {
final ProductHolder holder;
Product rowitems = productItems.get(position);
if (convertView == null) {
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(layoutId, parent, false);
holder = new ProductHolder();
holder.name = (TextView) convertView.findViewById(R.id.name);
holder.image = (ImageView) convertView
.findViewById(R.id.invite_click);
holder.image.setBackgroundResource(R.drawable.green);
convertView.setTag(holder);
}
else {
holder = (ProductHolder) convertView.getTag();
}
holder.image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (productItems.get(position).isCheck) {
productItems.get(position).isCheck = false;
// holder.image.setImageBitmap(null);
holder.image.setBackgroundResource(R.drawable.green);
} else {
productItems.get(position).isCheck = true;
holder.image
.setBackgroundResource(R.drawable.green_tick);
}
}
});
if (productItems.get(position).isCheck) {
productItems.get(position).isCheck = true;
holder.image.setBackgroundResource(R.drawable.green_tick);
} else {
productItems.get(position).isCheck = false;
holder.image.setImageBitmap(null);
holder.image.setBackgroundResource(R.drawable.green);
}
holder.name.setText(rowitems.getName());
Log.e("name----->", productItems.get(position).toString());
return convertView;
}
#Override
public int getCount() {
return productItems.size();
}
#Override
public Object getItem(int position) {
return productItems.get(position);
}
#Override
public long getItemId(int position) {
return productItems.indexOf(getItem(position));
}
}
}

Related

How to access arraylist of arraylist in adapters

Hi i am making android application. I am using json parsing in my application. first of all this is my json response
{
"Data": {
"headerText": "Revolution",
"productStartingPrice": "$38.78",
"sizeList": [
{
"textUpper": "Revolution for (Pink)",
"textLower": "$38.78",
"packList": [
{
"textUpper": "3 DOSES",
"textLower": "$38.78",
}
{
"textUpper": "6 DOSES",
"textLower": "$71.60",
}
]
},
{
"textUpper": "Revolution for (Blue)",
"textLower": "$46.92",
"packList": [
{
"textUpper": "3 DOSES",
"textLower": "$46.92",
}
{
"textUpper": "6 DOSES",
"textLower": "$79.56",
}
{
"textUpper": "12 DOSES",
"textLower": "$137.27",
}
]
}
]
},
"Status": 1,
"Message": "",
"UserMessage": ""
}
Now I am using custom alert dialog to load sizelist array and another dailog for packlist array. Now what i want is when user select (Pink) from sizelist then in second dailog i want to display 3 doses and 6 doses from packlist and when user select (Blue) i want to display 3 doses, 6 doses ,12 doses. Right now i am getting only last two items of (Blue) 6 doses ,12 doses. can any one help me to solve this?
private void showDialog(){
dialogf = new Dialog(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_main, null);
ListView lv = (ListView) view.findViewById(R.id.custom_list);
Button close_btn = (Button) view.findViewById(R.id.close_btn_sizelist);
sizeadapter = new CustomListAdapterSize(getActivity(), sizelists);
lv.setAdapter(sizeadapter);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
dialogf.setContentView(view);
dialogf.show();
close_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialogf.dismiss();
}
});
}
private void showDialogpacks(){
dialogfpacks = new Dialog(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_main_packs, null);
ListView lv = (ListView) view.findViewById(R.id.custom_list_packs);
Button close_btn = (Button) view.findViewById(R.id.close_btn_packlist);
adapterpacks = new CustomListAdaptertwo(getActivity(), sizelists);
lv.setAdapter(adapterpacks);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
dialogfpacks.setContentView(view);
dialogfpacks.show();
}
public class CustomListAdapterSize extends BaseAdapter {
private Context context;
private LayoutInflater inflater;
private List<ProductLandingSizeListModel> adaptersizelist;
private CheckBox selected =null;
private RadioButton mSelectedRB;
public CustomListAdapterSize(Context context,List<ProductLandingSizeListModel> movieItems) {
this.context = context;
this.adaptersizelist=movieItems;
}
#Override
public int getCount() {
return adaptersizelist.size();
}
#Override
public Object getItem(int position) {
return adaptersizelist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = LayoutInflater.from(context).inflate(R.layout.listitem_productsizes, null);
holder.txtproname = (TextView) convertView.findViewById(R.id.txtproductsizenames);
holder.txtproprice = (TextView) convertView.findViewById(R.id.txtproductsizeprice);
holder.radioBtn = (CheckBox)convertView.findViewById(R.id.productsize_radio);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
final ProductLandingSizeListModel m = adaptersizelist.get(position);
holder.txtproname.setText(m.getSizeList_textUpper());
holder.txtproprice.setText(m.getSizeList_textLower());
if (position == mSelectedPosition ) {
if (selected == null) {
holder.radioBtn.setChecked(true);
selected = holder.radioBtn;
}
}
if (position == mSelectedPosition )
holder.radioBtn.setChecked(true);
else
holder.radioBtn.setChecked(false);
holder.radioBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (selected != null) {
selected.setChecked(false);
}
mSelectedPosition =position;
if(mSelectedPositionpack!=0)
{
mSelectedPositionpack=0;
}
holder.radioBtn.setChecked(true);
selected = holder.radioBtn;
notifyDataSetChanged();
dialogf.dismiss();
showDialogpacks();
}
});
return convertView;
}
class ViewHolder{
TextView txtproname,txtproprice;
public CheckBox radioBtn;
}
}
public class CustomListAdaptertwo extends BaseAdapter {
private CheckBox selected =null;
private Context context;
private LayoutInflater inflater;
private List<ProductLandingSizeListModel> adaptersizelist;
public CustomListAdaptertwo(Context context,List<ProductLandingSizeListModel> adaptersizelist) {
this.context = context;
this.adaptersizelist=adaptersizelist;
inflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
if (adaptersizelist != null) {
return adaptersizelist.size();
}
return 0;
}
#Override
public Object getItem(int position) {
return adaptersizelist.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.custom_spinnertwo, null);
holder.txtproname = (TextView) convertView.findViewById(R.id.text_main_seentwo);
holder.txtproprice = (TextView) convertView.findViewById(R.id.sub_text_seentwo);
holder.checkpack = (CheckBox)convertView.findViewById(R.id.productpack_radio);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
final ProductLandingSizeListModel m = adaptersizelist.get(position);
for(int i=0;i<adaptersizelist.get(position).getPacklistmodel().size();i++)
{
System.out.println("PACK na data"+adaptersizelist.get(position).getPacklistmodel().get(i).getPackList_textUpper());
holder.txtproname.setText(adaptersizelist.get(position).getPacklistmodel().get(i).getPackList_textUpper());
holder.txtproprice.setText(adaptersizelist.get(position).getPacklistmodel().get(i).getPackList_textLower());
}
if (position == mSelectedPositionpack ) {
if (selected == null) {
holder.checkpack.setChecked(true);
selected = holder.checkpack;
}
}
if (position == mSelectedPositionpack )
holder.checkpack.setChecked(true);
else
holder.checkpack.setChecked(false);
holder.checkpack.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (selected != null) {
selected.setChecked(false);
}
mSelectedPositionpack =position;
holder.checkpack.setChecked(true);
selected = holder.checkpack;
// selected_pack_text.setText(movieItems.get(position)+" - "+"$"+packItems.get(position));
notifyDataSetChanged();
dialogfpacks.dismiss();
}
});
return convertView;
}
class ViewHolder{
TextView txtproname,txtproprice;
CheckBox checkpack;
}
}
Change your showDialogpacks like this.On click of the first dialog pass the position that is been clicked and then inside that pass only the item
inside sizelists for particular position.
private void showDialogpacks(int position){
dialogfpacks = new Dialog(getActivity());
View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_main_packs, null);
ListView lv = (ListView) view.findViewById(R.id.custom_list_packs);
Button close_btn = (Button) view.findViewById(R.id.close_btn_packlist);
adapterpacks = new CustomListAdaptertwo(getActivity(), sizelists.get(position).getPacklistmodel());
lv.setAdapter(adapterpacks);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
});
dialogfpacks.setContentView(view);
dialogfpacks.show();
}
Also change the second adapter list type to ProductLandingPackListModel.
public CustomListAdaptertwo(Context context,List<ProductLandingPackListModel> adaptersizelist) {
this.context = context;
this.adaptersizelist=adaptersizelist;
inflater = LayoutInflater.from(context);
}
And in the inside of the CustomAdapdtertwo getView method
final ProductLandingPackListModel model = adaptersizelist.get(position);
holder.txtproname.setText(model.getPackList_textUpper());
holder.txtproprice.setText(model.getPackList_textLower());
Hi Chris based upon size selection set packlist...update pack list of every size user selects

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

Listview with checkbox bug android

I have custom list view with checkbox, when I executed in my small mobile phone, if list view already had 5 items, then when I checked item 1, then item 5 will be checked also, if I checked item 5 then item 1 will be checked also, it happened with item (2-6,3-7,4-8, etc).
But if I had 4 items in my listview, it wont be happened. Here my listview adapter :
http://pastebin.com/mTEiXryf
Could you help me to solve my bug ? Thanks in advance
I suggest you to use Recyclerview
public class CardViewDataAdapter extends
RecyclerView.Adapter<CardViewDataAdapter.ViewHolder> {
private List<Student> stList;
public CardViewDataAdapter(List<Student> students) {
this.stList = students;
}
// Create new views
#Override
public CardViewDataAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View itemLayoutView = LayoutInflater.from(parent.getContext()).inflate(
R.layout.cardview_row, null);
// create ViewHolder
ViewHolder viewHolder = new ViewHolder(itemLayoutView);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
final int pos = position;
viewHolder.tvName.setText(stList.get(position).getName());
viewHolder.tvEmailId.setText(stList.get(position).getEmailId());
viewHolder.chkSelected.setChecked(stList.get(position).isSelected());
viewHolder.chkSelected.setTag(stList.get(position));
viewHolder.chkSelected.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Student contact = (Student) cb.getTag();
contact.setSelected(cb.isChecked());
stList.get(pos).setSelected(cb.isChecked());
Toast.makeText(
v.getContext(),
"Clicked on Checkbox: " + cb.getText() + " is "
+ cb.isChecked(), Toast.LENGTH_LONG).show();
}
});
}
// Return the size arraylist
#Override
public int getItemCount() {
return stList.size();
}
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView tvName;
public TextView tvEmailId;
public CheckBox chkSelected;
public Student singlestudent;
public ViewHolder(View itemLayoutView) {
super(itemLayoutView);
tvName = (TextView) itemLayoutView.findViewById(R.id.tvName);
tvEmailId = (TextView) itemLayoutView.findViewById(R.id.tvEmailId);
chkSelected = (CheckBox) itemLayoutView
.findViewById(R.id.chkSelected);
}
}
// method to access in activity after updating selection
public List<Student> getStudentist() {
return stList;
}
}
OR
If you want to use listview,then better you maintain Boolean array for checkbox,try this way this worked for me
public class CustomAdapter extends BaseAdapter {
private final LayoutInflater inflater;
private final Context context;
private List<ModelPooja> listData;
public CustomAdapter(Context mainActivity, List<ModelPooja> listData) {
context = mainActivity;
this.listData = listData;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return listData.size();
}
#Override
public Object getItem(int position) {
return listData.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.list_item_poojaselection, null);
holder.tv = (TextView) convertView.findViewById(R.id.list_item_poojaname);
holder.checks = (CheckBox) convertView.findViewById(R.id.list_item_poojacheck);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
holder.checks.setOnCheckedChangeListener(null);
holder.checks.setFocusable(false);
if (listData.get(position).isselected) {
holder.checks.setChecked(true);
} else {
holder.checks.setChecked(false);
}
holder.checks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton cb, boolean b) {
if (checkMaxLimit()) {
if (listData.get(position).isselected && b) {
holder.checks.setChecked(false);
listData.get(position).isselected = false;
} else {
holder.checks.setChecked(false);
listData.get(position).isselected = false;
Toast.makeText(context, "Max limit reached", Toast.LENGTH_SHORT).show();
}
} else {
if (b) {
listData.get(position).isselected = true;
} else {
listData.get(position).isselected = false;
}
}
}
});
holder.tv.setText(listData.get(position).getPOOJA_LISTING_NAME());
return convertView;
}
public boolean checkMaxLimit() {
int countermax = 0;
for(ModelPooja item : listData){
if(item.isselected){
countermax++;
}
}
return countermax >= 5;
}
public class ViewHolder {
TextView tv;
public CheckBox checks;
}
}
Here is solution- You had added holder.chkbox.setOnClickListener at wrong place just put it at right place. Replace your code with this code
if(convertView == null) {
convertView = myInflater.inflate(R.layout.customviewitemcashier, null);
holder = new ViewHolder();
holder.tvitemcode = (TextView) convertView.findViewById(R.id.tvitemcode);
holder.tvitemname = (TextView) convertView.findViewById(R.id.tvitemname);
holder.tvprice = (TextView) convertView.findViewById(R.id.tvprice);
holder.tvsubtotal = (TextView) convertView.findViewById(R.id.tvsubtotal);
holder.edtqty = (EditText) convertView.findViewById(R.id.edtqty);
holder.imgincrease = (TextView) convertView.findViewById(R.id.imgincrease);
holder.imgdecrease = (TextView) convertView.findViewById(R.id.imgdecrease);
holder.imgitem= (ImageView) convertView.findViewById(R.id.imgitem);
holder.chkbox = (CheckBox) convertView.findViewById(R.id.checkbox);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.chkbox.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (holder.chkbox.isChecked()) {
SQLiteDatabase dbinsert = dbHelper.getWritableDatabase();
String SQLinsert = "INSERT INTO itemcheckedcontainer (`item_code`) VALUES (" +
"'" + DataProcessorResult.get(position).getItemCode() + "')";
dbinsert.execSQL(SQLinsert);
} else {
SQLiteDatabase dbdelete = dbHelper.getWritableDatabase();
String SQLdelete = "DELETE FROM itemcheckedcontainer WHERE item_code=" +
"'" + DataProcessorResult.get(position).getItemCode() + "'";
dbdelete.execSQL(SQLdelete);
}
}
});
Your problem solved.

Multiple checkboxes get (de)selected when one is checked in Gridview - Android

So I have a Gridview where each grid item consists of an ImageView and a Checkbox. It calls Image Adapter to populate the grid dynamically. Now, when I select one checkbox, lets say number 5, another checkbox like number 12 gets selected automatically. Similar for deselection. I cannot figure out why this is happening. Any help will be appreciated. Thanks!
public class SignupFarmerCrop extends ActionBarActivity implements View.OnClickListener {
GridView gridView;
private ImageAdapter adpt;
private List<DistrictCommodity> localResponse;
private MediaPlayer mp;
private boolean[] thumbnailsselection;
private int count;
private PreferencesHelper oldSignup;
private String district;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_signup_farmer_crop);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
ImageButton sound = (ImageButton) findViewById(R.id.button);
sound.setOnClickListener(this);
oldSignup = new PreferencesHelper(this);
district = oldSignup.getStringPreferences("districtId");
String language = Locale.getDefault().getLanguage();
if (language.equals("en"))
language = "L001";
else
language = "L002";
// Exec async load task
new EndpointsDistrictCropAsyncTask().execute(new Pair<Context, String>(this, district),
new Pair<Context, String>(this, language));
gridView = (GridView) findViewById(R.id.gridView1);
adpt = new ImageAdapter(this, localResponse);
gridView.setAdapter(adpt);
public void onClick(View v) {
if (mp != null) mp.release();
mp = MediaPlayer.create(this, R.raw.fname);
mp.start();
}
/** Called when the user clicks a crop button */
public void goConfirm(View view) {
// Do something in response to button
Intent intent = new Intent(this, SignupConfirmActivity.class);
startActivity(intent);
}
#Override
protected void onDestroy() {
if(null!=mp){
mp.release();
}
super.onDestroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_signup_farmer_crop, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
public class ImageAdapter extends BaseAdapter {
private Context context;
private List<DistrictCommodity> crops;
private final Logger logger = Logger.getLogger(ImageAdapter.class.getName());
public ImageAdapter(Context context, List<DistrictCommodity> activeResponses) {
this.context = context;
this.crops = activeResponses;
}
public View getView(int position, View convertView, ViewGroup parent) {
View gridView = convertView;
ViewHolder holder;
if (gridView == null) {
holder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
gridView = inflater.inflate(R.layout.activity_signup_crop_grid, null);
holder.checkbox = (CheckBox) gridView.findViewById(R.id.grid_item_label);
holder.imageview = (ImageView) gridView.findViewById(R.id.grid_item_image);
gridView.setTag(holder);
}
else {
holder = (ViewHolder) gridView.getTag();
}
holder.checkbox.setId(position);
holder.imageview.setId(position);
holder.checkbox.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
int id = cb.getId();
logger.warning("Id of checkbox is: " + id);
if (thumbnailsselection[id]) {
cb.setChecked(false);
thumbnailsselection[id] = false;
} else {
cb.setChecked(true);
thumbnailsselection[id] = true;
}
}
});
holder.checkbox.setText(crops.get(position).getCommodity());
String crop = crops.get(position).getType();
logger.warning("Image file called is #drawable/" + crop + ".png and context is: " + context.getPackageName());
Drawable drawable = context.getResources().getDrawable(context.getResources()
.getIdentifier("#drawable/potato", null, context.getPackageName()));
holder.imageview.setImageDrawable(drawable);
holder.id = position;
return gridView;
}
#Override
public int getCount() {
return count;
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
public void setActiveDeals(List<DistrictCommodity> activeResponses) {
this.crops = activeResponses;
}
}
class ViewHolder {
ImageView imageview;
CheckBox checkbox;
int id;
}
}
MainActivity.java
private void enterEditMode() {
try {
listView.setAdapter(null);
listView.setOnItemClickListener(null);
db = new MySQLiteHelper(this);
//call the note object which hold all note object
List<note> note = db.getAllNotes();
int total = note.size();
//declare the values with specific number
String[] values = new String[total];
//add all the note innto the values
int counter = 0;
for (note note1 : note) {
values[counter] = note1.getSubject();
counter++;
}
db.close();
cbAdapter = new checkboxListviewAdapter(this,values);
// Assign adapter to ListView
listView.setAdapter(cbAdapter);
cbAdapter.notifyDataSetChanged();
} catch (Exception e) {
//tell user to send report
showMessage("Error!");
}
}
checkboxListviewAdapter.java
public class checkboxListviewAdapter extends BaseAdapter{
Context context;
String[] subjectList;
Boolean[] selectedList;
private LayoutInflater inflater;
public checkboxListviewAdapter (Context context, String[] subjectList ) {
this.context = context;
this.subjectList = subjectList;
selectedList = new Boolean[subjectList.length];
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < selectedList.length; i++){
selectedList[i] = false;
}
}
#Override
public int getCount() {
return subjectList.length;
}
#Override
public Object getItem(int position) {
return subjectList[position];
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
Holder holder = null;
if (convertView == null) {
holder = new Holder();
convertView = inflater.inflate(R.layout.checkbox_listview_text_black, null);
holder.tv = (TextView) convertView.findViewById(R.id.textview1);
holder.cb = (CheckBox) convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.cb.setChecked(selectedList[position]);
holder.tv.setText(subjectList[position]);
holder.cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selectedList[position] == false) {
selectedList[position] = true;
} else {
selectedList[position] = false;
}
}
});
return convertView;
}
static class Holder {
TextView tv;
CheckBox cb;
}
}
Explaination:
In checkboxListviewAdapter.java
1) Let's say you have 10 checkbox in your listview. So, create a boolean[] to hold your all checkbox's boolean value.
private boolean[] booleanList = new boolean[10];
2) In your constructor, use for loop to set booleanList's as false.
public checkboxListviewAdapter (Context context, String[] subjectList ) {
//this.context = context;
//this.subjectList = subjectList;
//selectedList = new Boolean[subjectList.length];
//inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
for (int i = 0; i < selectedList.length; i++){
selectedList[i] = false;
}
}
3) Now, in your getView, add the below code to get the boolean value from the booleanList and set the boolean value each time we scroll the listview.
holder.cb.setChecked(selectedList[position]);
4) Finally, to add a listener to your checkbox, use OnClickListener.
holder.cb.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(selectedList[position] == false) {
selectedList[position] = true;
} else {
selectedList[position] = false;
}
}
});
5) run the code and check the result.
You are saving the state of the checkbox in thumbnailsselection when it's clicked, but you don't use that state in getView() to set up the initial appearance of the checkbox. So you are probably getting random checkbox states from recycled views.
Call holder.checkbox.setState() with the state from thumbnailsselection to create the GridView item with the correct checkbox appearance.

CheckedTextView ListView with Headers - sort

I know this is not the first question about this topic with CheckBoxes and ListViews, but I don't know what to do..
I have a ListView with CheckedTextView and TextView and if I scroll some other's will get checked...
The views get resorted too and the enable/disable part (with the SharedPref) also don't work...
Used:
lalit3686 Blog
Android ListView Headers
So there is my code:
ActivtyMain.java
public class ActivityMain extends NavigationDrawerActivity{
#Override
public void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
context=this;
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
character_header_id.add(0);
character_header_id.add(character_original.size()+1);
character_header_id.add(character_original.size()+character_extension1.size()+2);
character_header_id.add(character_original.size()+character_extension1.size()+character_extension2.size()+3);
items.add(new CharacterHeader(getString(R.string.character_original)));
for(character key:character_original) {
String value=character_translation.get(key);
//System.out.println(value);
items.add(new CharacterListItem(value));
}
items.add(new CharacterHeader(getString(R.string.character_extension1)));
for(character key:character_extension1) {
String value=character_translation.get(key);
items.add(new CharacterListItem(value));
}
items.add(new CharacterHeader(getString(R.string.character_extension2)));
for(character key:character_extension2) {
String value=character_translation.get(key);
items.add(new CharacterListItem(value));
}
items.add(new CharacterHeader(getString(R.string.character_extension3)));
for(character key:character_extension3) {
String value=character_translation.get(key);
items.add(new CharacterListItem(value));
}
lv_charactere=((ListView) findViewById(R.id.character_list));
lv_charactere.setAdapter(new CharacterArrayAdapter(this, items));
//TODO check/unceck scroll problem
lv_charactere.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if(!character_header_id.contains(position)) {
CheckedTextView ctv = (CheckedTextView) view.getTag(R.id.listitem_character);
//CheckedTextView ctv = (CheckedTextView) view.findViewById(R.id.list_character);
System.out.println("character:position:"+position);
NavigationDrawerActivity.setCharacterCheckedTextViewChecked(ctv);
}
}
});
}
CharacterArrayAdapter.java
public class CharacterArrayAdapter extends ArrayAdapter<Item> {
private LayoutInflater mInflater;
private List<Item> items;
public enum RowTypeText {
CHECKED_ITEM, TITLE_ITEM
}
public CharacterArrayAdapter(Context context, List<Item> items) {
super(context, 0, items);
mInflater = LayoutInflater.from(context);
this.items=items;
}
#Override
public int getViewTypeCount() {
return RowTypeText.values().length;
}
#Override
public int getItemViewType(int position) {
return getItem(position).getViewType();
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
if(items.get(position).getClass().equals(CharacterListItem.class)) {
convertView = mInflater.inflate(R.layout.character_list_item, null);
viewHolder.checkedtextview = (CheckedTextView) convertView.findViewById(R.id.listitem_character);
viewHolder.checkedtextview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
int getPosition = (Integer) v.getTag(); // Here we get the position that we have set for the checkbox using setTag.
CheckedTextView ctv=((CheckedTextView)((CharacterListItem)items.get(getPosition)).getView(mInflater, v));
//ctv.setChecked(!((CheckedTextView) v).isChecked()); // Set the value of checkbox to maintain its state.
NavigationDrawerActivity.setCharacterCheckedTextViewChecked(ctv);
System.out.println("character:position:"+getPosition);
}
});
viewHolder.checkedtextview.setTag(position);
convertView.setTag(viewHolder);
convertView.setTag(R.id.listitem_character, viewHolder.checkedtextview);
}else{
convertView = mInflater.inflate(R.layout.character_header, null);
viewHolder.textview=(TextView) convertView.findViewById(R.id.listheader_character);
convertView.setTag(viewHolder);
convertView.setTag(R.id.listheader_menu, viewHolder.textview);
}
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
if(viewHolder.checkedtextview!=null) {
int pos=(int)viewHolder.checkedtextview.getTag(); // This line is important.
viewHolder.checkedtextview.setChecked(((CheckedTextView)((CharacterListItem)items.get(pos)).getView(mInflater, viewHolder.checkedtextview)).isChecked());
loadSettings(viewHolder, position);
return convertView;
}else{
return getItem(position).getView(mInflater, convertView);
}
//return getItem(position).getView(mInflater, convertView);
}
private void loadSettings(ViewHolder viewHolder, int position) {
//TODO select if selected before
for(Map.Entry<character, String> e:NavigationDrawerActivity.character_translation.entrySet()) {
if(e.getValue().equals(viewHolder.checkedtextview.getText())) {
if(NavigationDrawerActivity.character_playing.get(e.getKey())==0) {
viewHolder.checkedtextview.setChecked(false);
System.out.println("character:loadSaved: "+position+" checked:false");
}else{
if(viewHolder.checkedtextview.getText().equals(NavigationDrawerActivity.character_translation.get(character.DERNORMALEDORFBEWOHNER)) ||
viewHolder.checkedtextview.getText().equals(NavigationDrawerActivity.character_translation.get(character.WERWOLF))){
System.out.println("character:loadSaved: "+position+" disabled");
NavigationDrawerActivity.setCharacterCheckedTextViewEnabled(viewHolder.checkedtextview, false, true);
}else{
System.out.println("character:loadSaved: "+position+" checked:true");
viewHolder.checkedtextview.setChecked(true);
}
}
}
}
//TODO settings -> enable/disable
boolean ex1=NavigationDrawerActivity.spref.getBoolean(prefs.BOOLEAN_EXTENSION1.toString(), false);
boolean ex2=NavigationDrawerActivity.spref.getBoolean(prefs.BOOLEAN_EXTENSION2.toString(), false);
boolean ex3=NavigationDrawerActivity.spref.getBoolean(prefs.BOOLEAN_EXTENSION3.toString(), false);
for(Entry<character, String> e:NavigationDrawerActivity.character_translation.entrySet()) {
if(e.getValue().equals(viewHolder.checkedtextview.getText())) {
if(NavigationDrawerActivity.character_extension1.contains(e.getKey())) {
System.out.println("character:loadSaved: "+position+" enabled:"+ex1);
NavigationDrawerActivity.setCharacterCheckedTextViewEnabled(viewHolder.checkedtextview, ex1, false);
}
}
if(e.getValue().equals(viewHolder.checkedtextview.getText())) {
if(NavigationDrawerActivity.character_extension2.contains(e.getKey())) {
System.out.println("character:loadSaved: "+position+" enabled:"+ex2);
NavigationDrawerActivity.setCharacterCheckedTextViewEnabled(viewHolder.checkedtextview, ex2, false);
}
}
if(e.getValue().equals(viewHolder.checkedtextview.getText())) {
if(NavigationDrawerActivity.character_extension3.contains(e.getKey())) {
System.out.println("character:loadSaved: "+position+" enabled:"+ex3);
NavigationDrawerActivity.setCharacterCheckedTextViewEnabled(viewHolder.checkedtextview, ex3, false);
}
}
}
}
private static class ViewHolder{
protected CheckedTextView checkedtextview;
protected TextView textview;
}
}
NavigationDrawerActivity.java
public static void setCharacterCheckedTextViewChecked(CheckedTextView ctv) {
for(Entry<character, String> e:character_translation.entrySet()) {
if(e.getValue().equals(ctv.getText())) {
if(ctv.isChecked()) {
ctv.setChecked(false);
character_playing.put(e.getKey(),0);
}else{
ctv.setChecked(true);
if(e.getKey().equals(character.DERNORMALEDORFBEWOHNER) || e.getKey().equals(character.WERWOLF)) {
character_playing.put(e.getKey(),-1);
}else {
character_playing.put(e.getKey(),1);
}
}
break;
}
}
}
public static void setCharacterCheckedTextViewEnabled(CheckedTextView ctv, boolean enabled, boolean checked) {
ctv.setEnabled(enabled);
ctv.setClickable(enabled);
ctv.setLongClickable(enabled);
ctv.setChecked(checked);
}
ListViewCharacter.java
public class CharacterListItem implements Item {
private final String str;
public CharacterListItem(String text) {
this(text, false);
}
public CharacterListItem(String text, boolean selected) {
if(text==null) {
text="";
}
str=text;
}
#Override
public int getViewType() {
return RowTypeText.CHECKED_ITEM.ordinal();
}
#Override
public View getView(LayoutInflater inflater, View convertView) {
View view;
if (convertView == null) {
view = (View) inflater.inflate(R.layout.character_list_item, null);
} else {
view = convertView;
}
CheckedTextView tv=(CheckedTextView) view.findViewById(R.id.listitem_character);
tv.setText(str);
return view;
}
}
I think I posted all important code parts, if something is missing, please let me know
I don't know what to do..
getView
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
if(items.get(position).getClass().equals(CharacterListItem.class)) {
convertView = mInflater.inflate(R.layout.character_list_item, null);
viewHolder.checkedtextview = (CheckedTextView) convertView.findViewById(R.id.listitem_character);
viewHolder.checkedtextview.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
onClickListener(v);
}
});
convertView.setTag(viewHolder);
convertView.setTag(R.id.listitem_character, viewHolder.checkedtextview);
}else{
convertView = mInflater.inflate(R.layout.character_header, null);
viewHolder.textview=(TextView) convertView.findViewById(R.id.listheader_character);
convertView.setTag(viewHolder);
convertView.setTag(R.id.listheader_menu, viewHolder.textview);
}
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
if(viewHolder.checkedtextview!=null) {
viewHolder.checkedtextview.setTag(position); // This line is important.
viewHolder.checkedtextview.setText(items.get(position).getText());;
loadSettings(viewHolder);
return convertView;
}else{
return getItem(position).getView(mInflater, convertView);
}
important change (I think so):
only on the second part to set the position

Categories

Resources