6

Mam DialogFragment, który ma widok listy z CheckedTextView i pole wyboru u góry, aby zaznaczyć i odznaczyć wszystkie elementy w widoku listy. Próbuję ustawić State of the CheckedTextView na Checked/Unchecked w zależności od stanu pola wyboru CheckAll. Ale nie jestem w stanie zaktualizować widok odpowiednio za pomocą notifyDataSetChanged. enter image description herenotifyDataSetChanged nie aktualizuje 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" /> 

Odpowiedz

2

Próbuję ustawić stanu CheckedTextView do Sprawdzone/nierejestrowany w zależności od stanu Pole wyboru CheckAll. Ale nie jestem w stanie zaktualizować widok odpowiednio przy użyciu notifyDataSetChanged.

Dodano próbkę z kodem pytania jako przykładem moich odpowiedzi. Działa i can be found here (spójrz na to).

Odpowiedź Android-programisty działa także dlatego, że zasadniczo resetuje się adapter z nowymi elementami o poprawnym stanie za każdym razem, gdy użytkownik sprawdza/odznacza wszystkie CheckBoxs. Może to być marnotrawstwem (ale do przyjęcia, jeśli lista jest stosunkowo mała). Pamiętaj też, że jeśli klasa categoryName zmieni się w oknie dialogowym, musisz upewnić się, że została utworzona nowa Categories z poprawną nazwą (jeśli nie zmienisz nazwy kategorii, to nie jest to problem) gdy zostanie podjęta cała operacja CheckBox.

spróbować czegoś takiego:

  1. usunąć categoriesListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); czy to w kodzie
  2. modyfikować OnCheckedChangeListener do kontroli wszystkich CheckBox tak:

     @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. dodać OnItemClickListener do twoje kategorieListViewListView li ke to:

       @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) i getCheckStatus() (widzę, że masz isChecked metodę w Category można użyć dla uzyskania statusu logiczna) są metody w swojej klasie Category do ustawiania i uzyskanie statusu że poz

  5. w metodzie adaptera getView(), ustawić status takiego:

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

Zaktualizowano kod. Zmieniłem parametr stan_kategorii na wartość logiczną, czyli w jaki sposób będzie on przechowywany w danych. prawdziwe oznacza sprawdzone i viceversa. Teraz po załadowaniu okna dialogowego włączam stan na podstawie metody isChecked(). Zgodnie z kodem po kliknięciu sprawdź wszystko i dodałem kod. ale interfejs użytkownika nie odzwierciedla stanu sprawdzonego i niezaznaczonego. Ale w Log pokazuje właściwą wartość. z notifyDataSetChanged nie jestem w stanie zaktualizować interfejsu użytkownika. –

+1

@HarshaMV Jak wygląda układ twojego rzędu? Czy masz pojedynczy "CheckedTextView" lub "CheckTextView" zawinięty przez "LinearLayout" jak w poprzednim pytanie? – Luksprog

+0

Pojedynczy CheckedTextView. zaktualizuje kod o numerze –

2

Więc starają się ustawić wszystkie przedmioty sprawdzane na

setOnCheckedChangeListener

jak rozumiem. Przede wszystkim, jeśli chcesz, aby Twój

adapter.notifyDataSetChanged();

pracować trzeba dokonać zmian na swoich treści. Używasz

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

aby wypełnić swoją dialogowe i jego aktualizacji trzeba użyć tego samego jednego ze zmienionych danych lub utworzyć nową kartę. Aby korzystać z tego samego jeden w setOnCheckedChangeListener trzeba zrobić coś takiego:

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

     } 
    }); 

Spróbuj to i daj mi teraz, czy to działa dla Ciebie. :)

+0

Perfect. Wielkie dzięki to pomogło. tylko po to, aby zrozumieć, co robiłem źle. dlaczego nie mam tego wcześniej powiadomić? –

+1

Cieszę się, że to zadziałało. :) – hardartcore