I have a DialogFragment which has a list view with CheckedTextView and a checkbox at the top to Check and uncheck all the items in the list view. I am trying to set the State of the CheckedTextView to Checked/Unchecked depending on the state of the CheckAll Check box. But i am not able to update the view accordingly using notifyDataSetChanged.
CategoriesDialogFragment.java
public class CategoriesDialogFragment extends SherlockDialogFragment {
CheckBox checkAll;
ListView categoriesListView;
CategoriesListAdapter adapter;
static Category category;
String[] categories = new String[] { "Hill Station", "Beach", "Historic",
"Wild Life", "Waterfall", "River", "Archeology", "Hill Station",
"Beach", "Historic", "Wild Life", "Waterfall", "River",
"Archeology" };
Boolean[] categories_state = new Boolean[] { true, false, true, true, true,
true, false, true, false, true, true, true, true, false };
public static CategoriesDialogFragment newInstance() {
CategoriesDialogFragment frag = new CategoriesDialogFragment();
Bundle args = new Bundle();
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = new Dialog(MainActivity.context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_categories);
categoriesListView = (ListView) dialog
.findViewById(R.id.listViewDialog);
List<Category> theCategories = new ArrayList<Category>();
for (int i = 0; i < categories.length; i++) {
Boolean flag;
Category pl = new Category(categories[i], categories_state[i]);
theCategories.add(pl);
}
// categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
adapter = new CategoriesListAdapter(MainActivity.context,
R.layout.dialog_list_item_category, theCategories);
categoriesListView.setAdapter(adapter);
// List View Item Click Listener
categoriesListView
.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
CategoriesListAdapter adapter = (CategoriesListAdapter) parent
.getAdapter();
Category c = (Category) adapter.getItem(position);
c.setChecked(!c.getChecked());
adapter.notifyDataSetChanged();
}
});
// CheckAll CheckBox
checkAll = (CheckBox) dialog.findViewById(R.id.checkBoxAll);
checkAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Toast.makeText(MainActivity.context, "Check",
Toast.LENGTH_SHORT).show();
for (int i = 0; i < adapter.getCount(); i++) {
categoriesListView.setItemChecked(i, isChecked);
Log.i("Nomad", isChecked + " isChecked " + i);
}
adapter.notifyDataSetChanged();
/*
* if (isChecked) { Log.i("Nomad", "isChecked"); for (int i = 0;
* i < adapter.getCount(); i++) { category = adapter.getItem(i);
* category.setChecked(true); Log.i("Nomad", "isChecked "+i); }
* adapter.notifyDataSetChanged(); } else { Log.i("Nomad",
* "isUnChecked"); for (int i = 0; i < adapter.getCount(); i++)
* { category = adapter.getItem(i); category.setChecked(false);
* Log.i("Nomad", "isUnChecked "+i); }
* adapter.notifyDataSetChanged(); }
*/
}
});
return dialog;
}
private static class CategoriesListAdapter extends ArrayAdapter<Category> {
public Context mContext;
List<Category> mCategories;
public CategoriesListAdapter(Context context, int resource,
List<Category> categories) {
super(context, resource, categories);
// TODO Auto-generated constructor stub
this.mCategories = categories;
this.mContext = context;
}
public int getCount() {
return mCategories.size();
}
@Override
public Category getItem(int position) {
// TODO Auto-generated method stub
return mCategories.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
LayoutInflater viewInflater;
viewInflater = LayoutInflater.from(getContext());
convertView = viewInflater.inflate(
R.layout.dialog_list_item_category, null);
holder = new ViewHolder();
holder.categoryName = (CheckedTextView) convertView
.findViewById(R.id.categories_checkbox);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.categoryName.setText(mCategories.get(position)
.getCategoryName());
holder.categoryName.setChecked(mCategories.get(position)
.getChecked());
return convertView;
}
static class ViewHolder {
CheckedTextView categoryName;
}
}
}
Category.java
public class Category {
String categoryName = "";
private boolean checked = false;
public Category(String categoryName, boolean checked) {
this.categoryName = categoryName;
this.checked = checked;
}
public String getCategoryName() {
return categoryName;
}
public void setCategoryName(String categoryName) {
this.categoryName = categoryName;
}
public boolean getChecked() {
return checked;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
}
dialog_categories.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/parentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="8dip"
android:layout_marginStart="8dip"
android:background="@color/primary_white"
android:orientation="vertical" >
<LinearLayout
android:id="@+id/title_template"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginEnd="16dip"
android:layout_marginStart="16dip"
android:gravity="center_vertical|start"
android:orientation="horizontal"
android:paddingTop="5dp" >
<TextView
android:id="@+id/textView1"
style="?android:attr/textAppearanceLarge"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="10dp"
android:text="@string/dialog_category_title"
android:textColor="@color/primary_color"
android:textSize="22sp" />
<TextView
android:id="@+id/all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/dialog_category_checkbox"
android:textColor="@color/primary_color" />
<CheckBox
android:id="@+id/checkBoxAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingRight="6dp" />
</LinearLayout>
<View
android:id="@+id/titleDivider"
android:layout_width="match_parent"
android:layout_height="2dip"
android:background="@color/black" />
<LinearLayout
android:id="@+id/contentPanel"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:minHeight="64dp"
android:orientation="vertical" >
<ListView
android:id="@+id/listViewDialog"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
<LinearLayout
android:id="@+id/buttonPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<Button
android:id="@+id/button_category_ok"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/dialog_category_btn_ok"
android:textSize="14sp" />
</LinearLayout>
</LinearLayout>
dialog_list_item_category.xml
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/categories_checkbox"
android:layout_width="fill_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:checkMark="?android:attr/listChoiceIndicatorMultiple"
android:gravity="center_vertical"
android:onClick="toggle"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="12dp"
android:paddingTop="10dp"
android:text="sss" />
I am trying to set the State of the CheckedTextView to Checked/Unchecked depending on the state of the CheckAll Check box. But i am not able to update the view accordingly using notifyDataSetChanged.
Added a sample with the question's code to as an example of my answers. It works and can be found here(have a look at it).
Also, Android-Developer's answer works because you'll basically reset the adapter with new items with the correct state each time the user checks/unchecks the all CheckBoxs
. This could be wasteful(but acceptable if the list is relatively small). Also keep in mind that if the categoryName
of the Category
class changes in the dialog you'll need to make sure you construct the new Categories
with the correct name(if you don't modify the category name then this isn't an issue) when the all CheckBox
is acted upon.
Try something like this:
categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
if it's in your codemodify the OnCheckedChangeListener
for the check all CheckBox
like this:
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
Toast.makeText(getActivity(), "Check", Toast.LENGTH_SHORT)
.show();
Log.i("Nomad", "isChecked");
for (int i = 0; i < adapter.getCount(); i++) {
adapter.getItem(i).setChecked(isChecked);
Log.i("Nomad", "isChecked " + i);
}
adapter.notifyDataSetChanged();
}
add an OnItemClickListener
to your categoriesListView ListView
like this:
@Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
CategoriesListAdapter adapter = (CategoriesListAdapter) arg0
.getAdapter();
Category c = (Category) adapter.getItem(arg2);
c.setChecked(!c.getCheckStatus());
adapter.notifyDataSetChanged();
}
the setChecked(boolean)
and getCheckStatus()
(I see that you have a isChecked
method in Category
you could use that for getting the boolean status) are methods in your Category
class for setting and getting the status of that item
in the getView()
method of the adapter, set the status like this:
holder.categoryName.setChecked(mCategories.get(position)
.getCheckStatus());