notifyDataSetChanged无法更新的ListView [英] notifyDataSetChanged fails to update ListView

本文介绍了notifyDataSetChanged无法更新的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:机器人=htt​​p://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:机器人=htt​​p://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 重设新项目的适配器。这可能是浪费的(但可以接受,如果该列表比较小)。还要记住,如果类别名称范畴对话框类的变化,你需要确保你构建新的分类使用正确的名称(如果不修改类别名称,那么这是不是一个问题)时,所有的复选框正在采取行动。

尝试是这样的:

  1. 删除 categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); ,如果它在你的code
  2. 修改 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();
            }
     

  3. 添加 OnItemClickListener 您的 categoriesListView 的ListView 是这样的:

      @覆盖
                    公共无效onItemClick(适配器视图<>为arg0,查看ARG1,
                            INT ARG2,长ARG3){
                        CategoriesListAdapter适配器=(CategoriesListAdapter)为arg0
                                .getAdapter();
                        C类=(类别)adapter.getItem(ARG2);
                        c.setChecked(c.getCheckStatus()!);
                        adapter.notifyDataSetChanged();
                    }
     

  4. setChecked(布尔) getCheckStatus()(我看到你有一个器isChecked 类别,你可以用它获取布尔状态),在你的分类方法<方法/ code>类设置和获取该项目的状态。

  5. 在适配器的 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:

  1. remove the categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); if it's in your code
  2. modify 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();
            }
    

  3. 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();
                    }
    

  4. 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

  5. in the getView() method of the adapter, set the status like this:

    holder.categoryName.setChecked(mCategories.get(position)
                    .getCheckStatus());
    

这篇关于notifyDataSetChanged无法更新的ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆