notifyDataSetChanged无法更新的ListView [英] notifyDataSetChanged fails to update ListView
问题描述
我有一个DialogFragment其中有一个列表视图CheckedTextView和一个复选框顶部检查,并取消在列表视图中的所有项目。我想在CheckedTextView的状态设置为选中/未选中根据CheckAll复选框的状态。但我无法更新相应的使用notifyDataSetChanged的看法。
CategoriesDialogFragment.java
公共类CategoriesDialogFragment扩展SherlockDialogFragment {
复选框checkAll;
ListView控件categoriesListView;
CategoriesListAdapter适配器;
静态类别分类;
的String []类别=新的String [] {山站,海滩,历史,
野生动物,瀑布,河,考古,山站,
海滩,历史,野生动物,瀑布,河,
考古学 };
布尔[] categories_state =新布尔[] {真,假,真的,真的,真的,
真,假,虚,实,真,真,真,真,假};
公共静态CategoriesDialogFragment的newInstance(){
CategoriesDialogFragment FRAG =新CategoriesDialogFragment();
捆绑的args =新包();
frag.setArguments(参数);
返回FRAG;
}
@覆盖
公共对话onCreateDialog(包savedInstanceState){
最后一个对话框对话框=新的对话框(MainActivity.context);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.dialog_categories);
categoriesListView =(ListView控件)对话框
.findViewById(R.id.listViewDialog);
名单<类别> theCategories =新的ArrayList<类别>();
的for(int i = 0; I< categories.length;我++){
布尔标志;
类别PL =新的分类(类[我],categories_state [I]);
theCategories.add(PL);
}
// categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
适配器=新CategoriesListAdapter(MainActivity.context,
R.layout.dialog_list_item_category,theCategories);
categoriesListView.setAdapter(适配器);
//列表项点击监听器
categoriesListView
.setOnItemClickListener(新AdapterView.OnItemClickListener(){
@覆盖
公共无效onItemClick(适配器视图<>母公司视图中查看,
INT位置,长的id){
// TODO自动生成方法存根
CategoriesListAdapter适配器=(CategoriesListAdapter)父
.getAdapter();
C类=(类别)adapter.getItem(位置);
c.setChecked(c.getChecked()!);
adapter.notifyDataSetChanged();
}
});
// CheckAll复选框
checkAll =(复选框)dialog.findViewById(R.id.checkBoxAll);
checkAll.setOnCheckedChangeListener(新CompoundButton.OnCheckedChangeListener(){
@覆盖
公共无效onCheckedChanged(CompoundButton buttonView,
布尔器isChecked){
Toast.makeText(MainActivity.context,检查,
Toast.LENGTH_SHORT).show();
的for(int i = 0; I< adapter.getCount();我++){
categoriesListView.setItemChecked(ⅰ,器isChecked);
Log.i(保荐人,+器isChecked器isChecked+ I);
}
adapter.notifyDataSetChanged();
/ *
*如果(器isChecked){Log.i(保荐人,器isChecked);的for(int i = 0;
* I< adapter.getCount();我++){类别= adapter.getItem(ⅰ);
* category.setChecked(真正的); Log.i(保荐人,器isChecked+ I); }
* adapter.notifyDataSetChanged(); }其他{Log.i(保荐人,
*isUnChecked);的for(int i = 0; I< adapter.getCount();我++)
* {类别= adapter.getItem(ⅰ); category.setChecked(假);
* Log.i(保荐人,isUnChecked+ I); }
* adapter.notifyDataSetChanged(); }
* /
}
});
返回对话框;
}
私有静态类CategoriesListAdapter扩展ArrayAdapter<类别> {
公共语境mContext;
名单<类别> mCategories;
公共CategoriesListAdapter(上下文的背景下,INT资源,
名单<类别>类别){
超(背景下,资源类);
// TODO自动生成构造函数存根
this.mCategories =类别;
this.mContext =背景;
}
公众诠释getCount将(){
返回mCategories.size();
}
@覆盖
公共范畴的getItem(INT位置){
// TODO自动生成方法存根
返回mCategories.get(位置);
}
@覆盖
众长getItemId(INT位置){
返回的位置;
}
@覆盖
公共查看getView(INT位置,查看convertView,ViewGroup中父){
ViewHolder持有人;
如果(convertView == NULL){
LayoutInflater viewInflater;
viewInflater = LayoutInflater.from(的getContext());
convertView = viewInflater.inflate(
R.layout.dialog_list_item_category,NULL);
持有人=新ViewHolder();
holder.categoryName =(CheckedTextView)convertView
.findViewById(R.id.categories_checkbox);
convertView.setTag(保持器);
} 其他 {
支架=(ViewHolder)convertView.getTag();
}
holder.categoryName.setText(mCategories.get(位置)
.getCategoryName());
holder.categoryName.setChecked(mCategories.get(位置)
.getChecked());
返回convertView;
}
静态类ViewHolder {
CheckedTextView类别名;
}
}
}
Category.java
公共类分类{
字符串categoryName =;
私人布尔查= FALSE;
公共类(字符串categoryName,布尔检查){
this.categoryName =类别名称;
this.checked =检查;
}
公共字符串getCategoryName(){
返回类别名;
}
公共无效setCategoryName(字符串categoryName){
this.categoryName =类别名称;
}
公共布尔getChecked(){
返回检查;
}
公共无效setChecked(布尔检查){
this.checked =检查;
}
}
dialog_categories.xml
< XML版本=1.0编码=UTF-8&GT?;
< LinearLayout中的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:ID =@ + ID / parentPanel
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT
机器人:layout_marginEnd =8DIP
机器人:layout_marginStart =8DIP
机器人:背景=@色/ primary_white
机器人:方向=垂直>
<的LinearLayout
机器人:ID =@ + ID / title_template
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT
机器人:layout_marginEnd =16dip
机器人:layout_marginStart =16dip
机器人:重力=center_vertical |启动
机器人:方向=横向
机器人:paddingTop =5DP>
<的TextView
机器人:ID =@ + ID / textView1
风格=机器人:ATTR / textAppearanceLarge
机器人:layout_width =0dp
机器人:layout_height =WRAP_CONTENT
机器人:layout_weight =1
机器人:以下属性来=10dp
机器人:文本=@字符串/ dialog_category_title
机器人:文字颜色=@色/ primary_color
机器人:TEXTSIZE =22sp/>
<的TextView
机器人:ID =@ + ID /全部
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=@字符串/ dialog_category_checkbox
机器人:文字颜色=@色/ primary_color/>
<复选框
机器人:ID =@ + ID / checkBoxAll
机器人:layout_width =WRAP_CONTENT
机器人:layout_height =WRAP_CONTENT
机器人:paddingRight =6DP/>
< / LinearLayout中>
<查看
机器人:ID =@ + ID / titleDivider
机器人:layout_width =match_parent
机器人:layout_height =2DIP
机器人:背景=@彩色/黑白/>
<的LinearLayout
机器人:ID =@ + ID /的ContentPanel
机器人:layout_width =match_parent
机器人:layout_height =0dp
机器人:layout_weight =1
机器人:=了minHeight64dp
机器人:方向=垂直>
<的ListView
机器人:ID =@ + ID / listViewDialog
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT>
< / ListView控件>
< / LinearLayout中>
<的LinearLayout
机器人:ID =@ + ID / buttonPanel
机器人:layout_width =match_parent
机器人:layout_height =WRAP_CONTENT
机器人:方向=垂直>
<按钮
机器人:ID =@ + ID / button_category_ok
机器人:layout_width =FILL_PARENT
机器人:layout_height =WRAP_CONTENT
机器人:文本=@字符串/ dialog_category_btn_ok
机器人:TEXTSIZE =14sp/>
< / LinearLayout中>
< / LinearLayout中>
dialog_list_item_category.xml
< XML版本=1.0编码=UTF-8&GT?;
< CheckedTextView的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:ID =@ + ID / categories_checkbox
机器人:layout_width =FILL_PARENT
机器人:layout_height =机器人:ATTR /列表preferredItemHeight
机器人:对号=机器人:ATTR / listChoiceIndicatorMultiple
机器人:重力=center_vertical
机器人:的onClick =切换
机器人:paddingBottom会=10dp
机器人:以下属性来=10dp
机器人:paddingRight =12dp
机器人:paddingTop =10dp
机器人:文本=SSS/>
我想了CheckedTextView的状态设置为 选中/未选中取决于CheckAll复选框的状态。 但我不能够使用相应更新视图 notifyDataSetChanged。
添加问题的code样本,以作为我的答案的例子。它的工作原理和可以在这里(看看吧)。
发现另外,Android的开发者答案的作品,因为你基本上是用正确的状态,用户每次检查/取消选中所有 CheckBoxs
重设新项目的适配器。这可能是浪费的(但可以接受,如果该列表比较小)。还要记住,如果类别名称
的范畴
对话框类的变化,你需要确保你构建新的分类
使用正确的名称(如果不修改类别名称,那么这是不是一个问题)时,所有的复选框
正在采取行动。
尝试是这样的:
- 删除
categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
,如果它在你的code -
修改
OnCheckedChangeListener
用于检查所有的复选框
是这样的:@覆盖 公共无效onCheckedChanged(CompoundButton buttonView, 布尔器isChecked){ Toast.makeText(getActivity(),检查,Toast.LENGTH_SHORT) 。显示(); Log.i(保荐人,器isChecked); 的for(int i = 0; I< adapter.getCount();我++){ adapter.getItem(我).setChecked(器isChecked); Log.i(保荐人,器isChecked+ I); } adapter.notifyDataSetChanged(); }
-
添加
OnItemClickListener
您的 categoriesListView 的的ListView
是这样的:@覆盖 公共无效onItemClick(适配器视图<>为arg0,查看ARG1, INT ARG2,长ARG3){ CategoriesListAdapter适配器=(CategoriesListAdapter)为arg0 .getAdapter(); C类=(类别)adapter.getItem(ARG2); c.setChecked(c.getCheckStatus()!); adapter.notifyDataSetChanged(); }
-
在
setChecked(布尔)
和getCheckStatus()
(我看到你有一个器isChecked
在类别
,你可以用它获取布尔状态),在你的分类方法<方法/ code>类设置和获取该项目的状态。
-
在适配器的
getView()
方法,设置状态是这样的:holder.categoryName.setChecked(mCategories.get(位置) .getCheckStatus());
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:
- remove the
categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
if it's in your code modify the
OnCheckedChangeListener
for the check allCheckBox
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 categoriesListViewListView
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)
andgetCheckStatus()
(I see that you have aisChecked
method inCategory
you could use that for getting the boolean status) are methods in yourCategory
class for setting and getting the status of that itemin the
getView()
method of the adapter, set the status like this:holder.categoryName.setChecked(mCategories.get(position) .getCheckStatus());
这篇关于notifyDataSetChanged无法更新的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!