6

我有与CheckedTextView列表视图,并在顶部有一个复选框,选中或取消选中列表视图中的所有项的DialogFragment。我试图根据CheckAll复选框的状态将CheckedTextView的状态设置为Checked/Unchecked。但我无法使用notifyDataSetChanged相应地更新视图。 enter image description herenotifyDataSetChanged无法更新的ListView

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

回答

2

我想设置CheckedTextView到 取决于CheckAll复选框的状态选中/未选中的状态。 但我无法使用 notifyDataSetChanged相应地更新视图。

添加了一个带有问题代码的示例以作为我的答案的示例。它的工作原理和can be found here(看看它)。

此外,Android开发人员的答案有效,因为您基本上会在每次用户选中/取消选中全部CheckBoxs时,用正确的状态重置适配器。这可能是浪费的(但如果名单相对较小,则可以接受)。还要记住的是,如果对话框中的Category类变化categoryName你需要确保你构建新Categories使用正确的名称(如果不修改类别名称,那么这是不是一个问题)当全部CheckBox被采取行动时。

尝试这样:

  1. 删除categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);,如果它在你的代码
  2. 修改OnCheckedChangeListener用于检查所有CheckBox这样的:

     @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. 添加OnItemClickListener到您的类别列表查看ListView li柯本:

       @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. setChecked(boolean)getCheckStatus()(我看到你在Category一个isChecked方法,你可以利用它来获取布尔状态)是在你的Category类方法用于设置和获取的,状态项目

  5. 在适配器的getView()方法

    ,设置这样的状态:

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

更新了代码。我将category_state更改为布尔值,它将如何存储在数据中。真正意味着检查,反之亦然。现在,当我加载对话框时,我启用了基于isChecked()的状态。按照您的代码点击检查所有我添加的代码。但UI不反映已选中和未选中状态。但是在日志上它显示了正确的值。与notifyDataSetChanged无法更新用户界面。 –

+1

@HarshaMV你的行布局是怎样的?你有一个单独的'CheckedTextView'或者是一个''CheckTextView'',它由你之前的问题中的'LinearLayout'包装? – Luksprog

+0

单个CheckedTextView。将更新有问题的代码 –

2

所以,你想设置你的

setOnCheckedChangeListener

所有物品托运,我明白了。首先,如果你想使你的

adapter.notifyDataSetChanged();

工作,你必须使你的内容编辑。您正在使用

List<Category> theCategories = new ArrayList<Category>();

来填充对话框,并更新它,你必须使用同一个有变化的数据,或创建一个新的适配器。要使用在相同的一个您setOnCheckedChangeListener你必须做这样的事情:

checkAll.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

     @Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

      if(isChecked){ 
       theCategories.clear(); 
       Toast.makeText(MainActivity.context, "Check", Toast.LENGTH_SHORT).show(); 
       for (int i = 0; i < categories.length; i++) { 
        Category pl = new Category(categories[i], true); 
        theCategories.add(pl); 
       } 
       adapter.notifyDataSetChanged(); 
      } 

     } 
    }); 

试试这个,让我现在如果你的作品。 :)

+0

完美。非常感谢它帮助。只是为了理解我做错了什么。为什么我以前不通知? –

+1

很高兴为你工作。 :) – hardartcore

相关问题