Checked checkbox outside the adapter class on listView - android

In my Activity i have a list view and a check box.I created an adapter and do all stuff about it.In adapter i have 4 checkbox that loaded into list view.
I want to when user check this man checkBox in activity all checkBoxs on adapter is checked so in order to In activity first i find check box and finally i override setOnCheckedChangeListener method.
To find out number of view in adapter i am using TmpAdp.getCount().TmpAdp is my instance adapter.
This is a completed code :
chb_allCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
for (int i = 0; i < TmpAdp.getCount(); i++) {
View view = Glist.getChildAt(i);
CheckBox ch_item = view.findViewWithTag(i);
// CheckBox ch_item = view.findViewById(R.id.chb_send_info); // this is not work like findViewWithTag
ch_item.setChecked(true);
}
TmpAdp.checkAll(TmpAdp.getCount());
TmpAdp.notifyDataSetChanged();
} else {
}
}
});
The problem is, when i checked mani check box (chb_allCheck), none of them of check boxs inside adapter is not checked ?
This is a part of adapter class and getView method:
public View getView(final int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) Tmpcontext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.liststyle_saveed, parent, false);
BtnChangeToInPross = rowView.findViewById(R.id.BtnChangeToInPross);
TextView txtNosaziCodestr = rowView.findViewById(R.id.NosaziCodestr);
checkBox = rowView.findViewById(R.id.chb_send_info);
checkBox.setTag(position);
As you can see when i have clicked on Main check boxs, none of them of check box inside adapter is not checked

First of all make a Model class. In which you will take boolean isChecked.
Now in adapter class you will attach that model boolean to the list item checkbox.
checkbox.setChecked(model.isChecked());
When you check your main checkbox. Then just change isChecked boolean in your model list.
boolean isChecked = mainCheckBox.isChecked();
for(Model model : adapter.getList()){
model.setChecked(isChecked);
}
adapter.notifyDataSetChanged();
Here when you change checked status of model and notify your list. Then all your checkBox will be checked automatically, because these are attached to the model checked field.
It is logic, I did not write full code, you will make Model class, and will attach model by your list item.

Create a model class and make getter and setter method for check and uncheck Checkbox
Click of Main Checkbox in Activity
chb_allCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean
for (int i = 0; i < yourList.size; i++) {
if(checked){
yourlist.get(i).setCheckBoxAdapter(true);
}
else{
yourlist.get(i).setCheckBoxAdapter(false);
}
}
TmpAdp.notifyDataSetChanged();
}
});
in yourAdapterClass
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Get the data item for this position
CheckBoxModelClass modelclass= getItem(position);
if(modelclass.getCheckbox()){
adapterCheckBox.setChecked(true);
}
else{
adapterCheckBox.setChecked(false);
}
return convertView;
}

Tank you of your guys, You have made good suggestions but let me complete my way.
My problem was TmpAdp.notifyDataSetChanged();.When i removed this, code work completally.
I have completed my code and works perfectly and it can be an additional way to Select
all checkbox.
chb_allCheck.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
for (int i = 0; i < TmpAdp.getCount(); i++) {
View view = Glist.getChildAt(i);
CheckBox ch_item = view.findViewById(R.id.chb_send_info);
ch_item.setChecked(true);
}
TmpAdp.checkAll(TmpAdp.getCount());
} else {
for (int i = 0; i < TmpAdp.getCount(); i++) {
View view = Glist.getChildAt(i);
CheckBox ch_item = view.findViewById(R.id.chb_send_info);
ch_item.setChecked(false);
}
TmpAdp.removeAll();
}
}
});

Related

how to get checked multiple values using custom adapter in android

I have listview with custom adapter. Every element of this listview has checkbox. Standart function .isChecked() does not work.
someActivity.java
#Override
protected void onCreate(Bundle savedInstanceState) {
btnShare.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<Boolean> listCheck;
listCheck = new ArrayList<Boolean>();
for (int i = 0; i < CA_main_trx.editModelArrayList.size(); i++){
Boolean stat = CA_main_trx.editModelArrayList.get(i).getCheckShare();
String nilaiPcs = CA_main_trx.editModelArrayList.get(i).getTextView_main_trx2();
Log.d(TAG, "onClick: --a" + nilaiPcs);
Log.d(TAG, "onClick: --a" + stat);
}
}
});
CustomeAdapter
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
final String TAG = "CA_Main_Trx : ";
...
holder.checkShare.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
String id = editModelArrayList.get(position).getTextView_main_trx0();
Log.d(TAG, "onCheckedChanged: True"+id);
}
else
Log.d(TAG, "onCheckedChanged: False");
}
});
...
model
package com.m.t;
public class EM_main_trx {
private boolean checkShare;
public Boolean getCheckShare() {return checkShare;}
public void setCheckShare(Boolean checkShare) {
this.checkShare = checkShare;
}
}
When checked in custome Adapter i get the checked status. But when i get the data using button in my mainactivity i got stuck. just got null.
Some my reference :
Android: Get checked checkbox values
Finding the Checked state of checkbox in a custom listview
how to get the the multiple checkbox values using custom adapter in android
Android List View Custom Adapter with Checkbox multiple selection and Search Listview
Checked values of CheckBox with Custom Listview android
Just update part of custome adapter to this :
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
editModelArrayList.get(position).setCheckShare(b);
}

Getting the checked states of a radio button in all the items in a recycler view

I have a RecyclerView which holds 10 views each having a CheckBox. Now, in my main activity when a menu button named "POST" is pressed I want to know whether all the CheckBox in each of the views of the RecyclerView is checked or not.
How can I implement this?
I advise you to pass additional variable isChecked inside every model of a list of models passed to RecyclerView.
Like that:
public class Model {
private boolean isChecked;
public boolean isChecked() {
return isChecked;
}
public void setChecked(boolean checked) {
isChecked = checked;
}
}
Then inside your RecyclerView ViewHolder, create a constructor:
public ListViewHolder(View view) {
super(view);
switchCompat = (SwitchCompat) view.findViewById(R.id.add_switch);
switchCompat.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
getItemAt(getLayoutPosition()).setChecked(isChecked);
}
});
}
Then to get all button states just iterate through the list of models in Your activity:
public boolean areAllChecked() {
for (int i = 0; i < adapter.getItemCount(); i++) {
Model model = adapter.getItemAt(i);
if (!model .isChecked()) {
return false;
}
}
return true;
}
Add a boolean isChecked in your model class (Item which you are adding to RecyclerView Adapter)
In your adapter onBindViewHolder implement onCheckedChangeListener for your checkbox and set isChecked appropriately.
implement a isChecked(int position) method in your adapter. It should return checked value of the items specified by position
in your fragment/activity iterate through adapter items and find out if all items are checked or not.
Track the state of each checkbox in the adapter.
To do so let it have an map that stores a boolean value bound to a unique key for each checkbox. And also let it implement the OnCheckedChangeListener.
MyAdapter extends RecyclerView.Adapter implements OnCheckedChangeListener {
private Map<Object, Boolean> checkboxStates = new HasMap<>();
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
checkboxStates.put(buttonView.getTag(), isChecked);
}
public Map<Object, Boolean> getCheckboxStates() {
//We don't want the caller to modify adapter state.
return Collections.unmodifiableMap(this.checkboxStates);
}
//other code
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
//your code
CheckBox cb;
//assuming that we have the reference to the cb view
//also assuming that cb has a unique identifiable tag assigned from the model
cb.setOnCheckedChangeListener(this);
if (this.checkboxStates.containsKey(cb.getTag()) {
cb.setChecked(this.checkboxStates.get(cb.getTag());
} else {
this.checkboxStates.put(cb.getTag(), cb.isChecked());
}
}
}
With this you can call the getCheckboxStates to get the states of each checkbox that was visible.
The key point here is that you need something unique identifiable for each item in the dataset that can be used as a tag for each checkbox that represents that item.

Check and Uncheck All CheckBoxes in ListView

I was surprised that I couldn't find an existing answer on Stack that I could use for this, so here I am.
I have a ListFragment with a list attached to a SimpleCursorAdapter comprised of the rows defined by the following row.xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="6dip" >
<CheckBox
android:id="#+id/story_check_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:focusable="false"
android:focusableInTouchMode="false" />
<TextView
android:id="#+id/story"
android:layout_width="wrap_content"
android:layout_height="24sp"
android:lines="1"
android:scrollHorizontally="true"
android:singleLine="true"
android:layout_alignBaseline="#+id/story_check_box"
android:layout_alignBottom="#+id/story_check_box"
android:layout_toRightOf="#+id/story_check_box" />
</RelativeLayout>
I connect the list with the adapter with the following code in my ListFragment:
adapter = new SimpleCursorAdapter(getActivity(), R.layout.row, null, new String[] { CProvider.Stories.TITLE }, new int[] { R.id.story }, 0);
setListAdapter(adapter);
I then try to use a CheckBox in my fragment to toggle all the list checkboxes as follows:
CheckBox selectAll = (CheckBox) rootView.findViewById(R.id.select_check_box);
selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final ListView listView = getListView();
for(int i=0; i < getListAdapter().getCount(); i++){
View view = getViewByPosition(i, listView);
CheckBox cb = (CheckBox)view.findViewById(R.id.story_check_box);
if (isChecked) {
cb.setChecked(true);
}
else {
cb.setChecked(false);
}
}
}
});
I got getViewByPositionfrom here: Get ListView children that are not in view, and that almost works, but a few of the checkboxes don't get checked (and there is a pattern to it, but I can't seem to figure it out). It also seems a bit kludgier than I would think is necessary.
I want the checkboxes on the left, so I don't want to use checkedtextviews. Maybe I need to extend CursorAdapter and override getView?
Thanks in advance.
Maybe I'm not correctly understanding your question but what I understood was that you wanted to check and uncheck all the checkboxes thanks to one "Select All checkbox".
Then, what I would do is to put the state of the "select all checkbox" as a variable of the class (as a boolean) which is overwritten by your selectAll.setOnCheckedChangeListener and say to the adapter "Hey, my state changed!" every time the checkbox changed its state.
Something like this:
class Dummy{
boolean isAllSelected = false;
Checkbox selectAll = (find or create your CheckBox)
selectAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) isAllSelected = true;
else isAllSelected = false;
listView.getAdapter().notifyDataSetChanged();
}
}
And then, you just have to override the getView() of this adapter (like you suggested) adding a "if (isAllSlected)" condition.
To me, it sounds the easiest to do but it's maybe not that good to call the notifyDataSetChanged() method every time the user clicks on a checkbox (it's not that efficient for so minor changes). Anyway, hope it helps (the code I wrote is maybe not with the correct syntax: I wrote it directly on the website form)!
Below is what I wound up doing. In addition to taking care of the "select all/ unselect all" functionality, it handles checking/unchecking a checkbox when the text of a list item is selected/unselected, and vice versa. I was concerned about getView being called frequently, but setItemChecked causes getView to be called no matter what, so there's a limit to how much calls to getView can be avoided. As ataulm mentioned in a comment, maybe a composite view would a solution with less fuss.
In onCreateView:
selectAllCheckBox = (CheckBox) rootView.findViewById(R.id.select_all_check_box);
selectAllCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
final ListView listView = getListView();
for(int i=0; i < getListAdapter().getCount(); i++){
listView.setItemChecked(i, isChecked);
}
}
});
I also created a custom SimpleCursorAdapter with the following code, which also uses a simple ViewHolder class. In getView I check which items in the list are selected and check the checkboxes corresponding to those items. There's also code that sets a list item as selected or not if its corresponding checkbox has been clicked (i.e., checked or unchecked).
class AvailableCursorAdapter extends SimpleCursorAdapter {
AvailableCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder)row.getTag();
if (holder == null) {
holder = new ViewHolder(row);
row.setTag(holder);
}
holder.storyCheckBox.setChecked(false);
holder.story.setTextColor(Color.LTGRAY);
long [] checkedIds = getListView().getCheckedItemIds();
if (checkedIds != null) {
for (int i = 0; i < checkedIds.length; i++) {
if (checkedIds[i] == getListAdapter().getItemId(position)) {
holder.storyCheckBox.setChecked(true);
holder.story.setTextColor(Color.WHITE);
break;
}
}
}
final boolean isChecked = holder.storyCheckBox.isChecked();
holder.storyCheckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
getListView().setItemChecked(position, !isChecked);
}
});
return(row);
}
}
.
class ViewHolder {
CheckBox storyCheckBox;
TextView story = null;
ViewHolder(final View row) {
storyCheckBox = (CheckBox) row.findViewById(R.id.story_check_box);
story = (TextView) row.findViewById(R.id.story);
}
}
Finally, the following code causes getView to be called when a single ListItem is clicked, so that its corresponding checkbox gets selected or unselected, as appropriate:
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
ViewHolder holder = (ViewHolder) v.getTag();
holder.storyCheckBox.setChecked(false);
holder.story.setTextColor(Color.LTGRAY);
long [] checkedIds = l.getCheckedItemIds();
if (checkedIds != null) {
for (int i = 0; i < checkedIds.length; i++) {
if (checkedIds[i] == getListAdapter().getItemId(position)) {
holder.storyCheckBox.setChecked(true);
holder.story.setTextColor(Color.WHITE);
break;
}
}
}
}

Setting checkbox dynamically from sqlite in a Fragment

I'm having trouble figuring out the best way to store and display checkboxes in a listview.
Right now I have the code in the getView method:
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
//final ViewHolder holder;
if (convertView == null) {
convertView = getActivity().getLayoutInflater().inflate(R.layout.grid_item, null);
}
ImageView img = (ImageView) convertView.findViewById(R.id.grid_item_img);
cb = (CheckBox) convertView.findViewById(R.id.chk_box_griditem);
if(photos.get(position).getIshidden()){
cb.setChecked(false);
}else{
cb.setChecked(true);
}
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
MySQLiteHelper db = MySQLiteHelper.getInstance(getActivity());
Log.d("checkbox", "status: " + photos.get(position).getIshidden());
if (isChecked) {
photos.get(position).setIshidden(true);
cb.setChecked(true);
Log.d("checkbox", "isChecked");
db.updatePhoto(photos.get(position));
} else {
photos.get(position).setIshidden(false);
cb.setChecked(false);
Log.d("checkbox", "isCheckedelse");
db.updatePhoto(photos.get(position));
}
}
});
imageLoader.displayImage(imgUrls[position], img, options, animateFirstListener);
//img.setImageResource(mImgRes);
return convertView;
}
The db helper takes a photo object as an argument and updates the row if it exists. So right now I update the current photo object isHidden() to be true or false then pass the updated object to db helper.
The physical database seems to be updating correctly. However a problem occurs when the checkboxes state is being set. The checkboxes seem to be randomly set as checked or unchecked.
Also I feel like doing this in the getView is cpu greedy but am not sure how else to do this.
First remove cb.setOnCheckedChangeListener...You do not need to set the OnCheckedChangeListener every time getView is called.you have already written the below code which will set check-box state(checked or unchecked) when list-view loads.
if(photos.get(position).getIshidden())
cb.setChecked(false);
else
cb.setChecked(true);
Now set onItemClick listener as below on list view :
mListView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position,long arg3)
{
MySQLiteHelper db = MySQLiteHelper.getInstance(getActivity());
Log.d("checkbox", "status: " + photos.get(position).getIshidden());
if(photos.get(position).getIshidden())
{
((CheckBox)arg0.getChildAt(position).findViewById(R.id.chk_box_griditem)).setChecked(true);
photos.get(position).setIshidden(false);
db.updatePhoto(photos.get(position));
}
else
{
((CheckBox)arg0.getChildAt(position).findViewById(R.id.chk_box_griditem)).setChecked(false);
photos.get(position).setIshidden(true);
db.updatePhoto(photos.get(position));
}
}
});
by that way you can check or uncheck the check-box and at the same time the check-box state(checked or unchecked) will be saved in your database.
I hope it will work.If not let me know..:)
When you are initializing your checkbox you set the Check state to false if the image is hidden.
if(photos.get(position).getIshidden()){
cb.setChecked(false);
}else{
cb.setChecked(true);
}
But in the Listener you set the image to hide when the checkbox is checked.
if (isChecked) {
photos.get(position).setIshidden(true);
...
This is actually the inverse. You are probably disturbed by that.
And you do not have to set the checked state again in the listener.
So your code in the listener could look like this:
if (isChecked) {
photos.get(position).setIshidden(false);
Log.d("checkbox", "isChecked");
db.updatePhoto(photos.get(position));
} else {
photos.get(position).setIshidden(true);
Log.d("checkbox", "isCheckedelse");
db.updatePhoto(photos.get(position));
}
1) Do not set the checkbox in the listener
2) Attach the listener in the checkbox only if convertView is null (i.e. when inflating). When you get your view from the convertview it has its listener set already.
Change and then log. OnCheckedChange you can get away with no if statements and just use the boolean. You don't need to set the value in of the check box in the checkedchanged listener. Intialize db in onResume so it's available no telling how many times a user will click something and the db initialization will slow things down.
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
photos.get(position).setIshidden(isChecked);
db.updatePhoto(photos.get(position));
Log.d("checkbox", isChecked.toString());
}
});
#Override
protected void onResume() {
if (db==null) {
db = MySQLiteHelper.getInstance(getActivity());
}
}

Targeting specific checkbox with tag in listview

In my app I have a list with rows, each containing an image, text, and a checkbox. I overrode the getView method of my simpleadapter to include a tag for each checkbox based on its position in the row (code is here http://www.heypasteit.com/clip/YME ... bs and bs1 are booleans). That way I could tell which checkbox was being changed when onCheckedChanged was invoked. However, I need to set the state of individual checkboxes manually. For example, set the state of the checkbox with tag "3" (the checkbox on row 3) to "true."
Any help on this would be much appreciated!
You can replace your approach with an array of booleans. For example, if you have 15 elements in array, you can create a boolean[15], and change state of different positions when user clicks a checkbox, as well as set the initial state in the beginning.
Not a perfect example, but I hope you'll get the idea:
public class YourActivity extends Activity {
protected boolean[] checkStates;
protected void onCreate(android.os.Bundle savedInstanceState) {
//... Some of your code where you get a list of you objects
checkStates = new boolean[list.size()];
// As an example, let's check some of them:
checkStates[3] = true;
checkStates[7] = true;
//.. Something more
};
SimpleAdapter adapter = new SimpleAdapter(this, list, R.layout.rowsecond, new String[] {"icon", "name"}, new int[] {R.id.image1, R.id.text1}) {
public View getView(int position, View convertView, ViewGroup parent) {
final View v = super.getView(position, convertView, parent);
boxer = (CheckBox)v.findViewById(R.id.checkbox);
boxer.setTag(position);
boxer.setOnCheckedChangeListener(checkedChangeListener);
boxer.setChecked(checkStates[position]);
return v;
}
private final OnCheckedChangeListener checkedChangeListener = new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked) {
final Integer position = (Integer) buttonView.getTag();
checkStates[position] = isChecked;
}
};
};
}
Don't forget to call yourAdapterInstance.notifyDataSetChanged() if you are trying to update checkboxes states from outside of checkedChangeListener and after initial onCreate() method;

Categories

Resources