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

本文介绍了notifyDataSetChanged 无法更新 ListView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 DialogFragment,它有一个带有 CheckedTextView 的列表视图和一个顶部的复选框,用于检查和取消选中列表视图中的所有项目.我试图根据 CheckAll 复选框的状态将 CheckedTextView 的状态设置为选中/未选中.但是我无法使用 notifyDataSetChanged 相应地更新视图.

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

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" />

推荐答案

我正在尝试将 CheckedTextView 的状态设置为选中/未选中取决于 CheckAll 复选框的状态.但我无法相应地使用更新视图通知数据集已更改.

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

此外,Android-Developer 的答案有效,因为每次用户选中/取消选中所有 CheckBoxs 时,您基本上都会使用具有正确状态的新项目重置适配器.这可能很浪费(但如果列表相对较小,则可以接受).还要记住,如果 Category 类的 categoryName 在对话框中发生变化,您需要确保使用以下命令构造新的 Categories对所有 CheckBox 采取行动时的正确名称(如果您不修改类别名称,则这不是问题).

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.

试试这样的:

  1. 删除 categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 如果它在您的代码中
  2. 修改 OnCheckedChangeListener 以检查所有 CheckBox 像这样:

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

  • OnItemClickListener 添加到您的 categoriesListView ListView 中,如下所示:

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

  • setChecked(boolean)getCheckStatus()(我看到你在 Category 中有一个 isChecked 方法 您可以使用它来获取布尔状态)是 Category 类中用于设置和获取该项目状态的方法

  • 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

    在适配器的getView()方法中,设置状态如下:

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

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

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

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