2016-06-30 14 views
1

Ich habe das folgende Problem.Aktualisieren von ListView nach Auswahl des Elements aus dem Dialogfenster

Ich habe eine ListView, die mir Artikel mit verschiedenen Kategorien anzeigt. Wenn ich eine Kategorie aus meinem Dialogfenster auswähle und die Positivtaste "OK" drücke, möchte ich meine ListView aktualisieren, dass sie jetzt nur die Artikel aus der Kategorie auflistet, die im Dialogfenster ausgewählt wurden.

Ich habe eine Schnittstelle in der DialogFragment erstellt, die ein Rückruf ist, um Wert aus dem Dialog zu erhalten.

Dies ist die Klasse:

public class SelectFilterDialog extends DialogFragment implements DialogInterface.OnClickListener{ 
private static int mSelectedIndex; 
private static String mSelectedCategory; 
private String[] categories = {"All", "Announcements","Commerce","Development", "Distributions", "Front","Kernel","Legal", "Letters", "Press", "Security"}; 
static OnDialogSelectListener mDialogSelectorCallback; 


//callback method to get values from a Dialog 
public interface OnDialogSelectListener{ 
    public void onSelectedOption(); 
} 

public static SelectFilterDialog newInstance(int selected) { 
    final SelectFilterDialog dialog = new SelectFilterDialog(); 
    mSelectedIndex = selected; 
    return dialog; 
} 

public Dialog onCreateDialog(Bundle savedInstanceState) { 

    final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); 
    builder.setTitle("Select Filter"); 
    builder.setPositiveButton("OK", this); 
    builder.setNegativeButton("Cancel", this); 
    builder.setSingleChoiceItems(categories, mSelectedIndex, this); 

    return builder.create(); 
} 

@Override 
public void onClick(DialogInterface dialog, int which) { 
    switch (which){ 
     case Dialog.BUTTON_POSITIVE:{ 
      dialog.dismiss(); 
      mDialogSelectorCallback.onSelectedOption(); 
     }break; 
     case Dialog.BUTTON_NEGATIVE:{ 
      dialog.cancel(); 
     }break; 
     default: 
      mSelectedIndex = which; 
      setSelectedCategory(categories[which]); 
      break; 
    } 
} 

public void setDialogSelectListener(OnDialogSelectListener listener){ 
    this.mDialogSelectorCallback = listener; 
} 

public void setSelectedCategory(String category){ 
    this.mSelectedCategory = category; 
} 

public static String getSelectedCategory(){ 
    return mSelectedCategory; 
} 

public static int getSelectedIndex(){ 
    return mSelectedIndex; 
} 

}

In meiner SearchFragment Klasse, ich die Liste zeigen und die Schnittstelle vom SelectFilterDialog Fragmente implementieren. In dem Verfahren, aktualisiere ich die selectedCategory, nach Drücken der Taste OK, und aktualisieren Sie dann den Adapter mit notifyDataSetChanged()

SearchFragment:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case R.id.menu_bar_filter: { 
      showDialog(); 
     } 
    } 
    return super.onOptionsItemSelected(item); 
} 

void showDialog() { 
    SelectFilterDialog dialog = SelectFilterDialog.newInstance(preSelectedValue); 
    dialog.setDialogSelectListener(this); 
    dialog.show(getActivity().getFragmentManager(), "dialog"); 
} 

@Override 
public void onSelectedOption() { 
    selectedCategory = dialog.getSelectedCategory(); 
    preSelectedValue = dialog.getSelectedIndex(); 

    Log.i(TAG, "selectedCategory : " +selectedCategory); 
    article_list_adapter.updateCategory(selectedCategory); 
} 

In meinem Adapter, ich die Kategorie in meiner updateCategory erhalten und Füllen Sie die aktuelle Artikelliste mit den Artikeln mit der korrekten Kategorie. Das funktioniert gut. Danach rufe ich NotifyDataSetChanged auf, um die Ansicht zu aktualisieren.

public void updateCategory(String category) { 
    this.currentArticles.clear(); 
    this.selectedCategory = category; 
    for (Article article : entireArticles) { 
     if (category.equals(article.getCategory())) { 
      currentArticles.add(article); 
     } 
    } 
    notifyDataSetChanged(); 
} 
    notifyDataSetChanged(); 
} 

Aber in der getView löst es eine IndexOutOfBounce Ausnahme. Nach Auswahl einer Kategorie aus dem Dialogfeld, z. B. "Kernel", fügt es nur meine 3 Kernel-Kategorien zur aktuellenArtikelliste hinzu, was in Ordnung ist. Aber die Aussage getView int:

Article currentArticle = currentArticles.get(_position);  

Es auf Indexpunkte 3, obwohl es nur drei Elemente in der Liste enthalten sind.

java.lang.IndexOutOfBoundsException: Invalid index 3, size is 3 
                       at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) 
                       at java.util.ArrayList.get(ArrayList.java:308) 
                       at klinar.kronlachner.binder.app.Article_List_Adapter.getView(Article_List_Adapter.java:99)  

Können Sie mir helfen? :)

public Article_List_Adapter(Context _c, int textViewResourceId, List<Article> articles) { 
    super(_c, textViewResourceId, articles); 
    this.entireArticles = new ArrayList<Article>(); 
    this.currentArticles = new ArrayList<Article>(); 
    entireArticles.addAll(articles); 
    currentArticles.addAll(articles); 
    this.storedArticles = new ArrayList<Article>(articles); 
} 

public View getView(int _position, View _convertView, ViewGroup _parent) { 
    View view = _convertView; 
    ViewHolder viewHolder; 

    if (view == null) { 
     LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     view = inflater.inflate(R.layout.article_list_row, null); 
     viewHolder = new ViewHolder(); 
     viewHolder.article_icon = (ImageView) view.findViewById(R.id.article_category_icon); 
     viewHolder.articleTitle = (TextView) view.findViewById(R.id.article_title); 
     viewHolder.articleCategory = (TextView) view.findViewById(R.id.article_category); 
     viewHolder.articleDate = (TextView) view.findViewById(R.id.article_date); 
     viewHolder.articleAuthor = (TextView) view.findViewById(R.id.article_author); 
     view.setTag(viewHolder); 
    } else { 
     viewHolder = (ViewHolder) _convertView.getTag(); 
    } 


    //Find the article to work with 
    Article currentArticle = currentArticles.get(_position); 


    //fill the Article_View 
    switch (currentArticle.getCategory()) { 
     case "Kernel": { 
      viewHolder.article_icon.setImageResource(R.drawable.ic_list_letter_k); 
     } 
     break; 
     case "Security": { 
      viewHolder.article_icon.setImageResource(R.drawable.ic_list_letter_s); 
     } 
     break; 
     default: { 
      viewHolder.article_icon.setImageResource(R.drawable.ic_list_letter_s); 
     } 
    } 
    viewHolder.articleTitle.setText(currentArticle.getTitle()); 
    viewHolder.articleCategory.setText(currentArticle.getCategory()); 
    viewHolder.articleDate.setText(currentArticle.getDate()); 
    viewHolder.articleAuthor.setText(currentArticle.getAuthor()); 


    return view; 
+0

Verwenden 'String.equals' statt' == 'für den Vergleich von String-Werten –

+0

eingestellt, dass, aber das löst nicht mein Problem :( –

+0

Ich denke, müssen' nennen mSelectedIndex = die; setSelectedCategory (Kategorien [die ]); 'in' Fall Dialog.BUTTON_POSITIVE: ' –

Antwort

0

diese Klasse in Ihrem Adapter Sie zwei Liste eine für AllCategoryArticle erstellen und eine andere für currentCategoryArticle.

class ArticleAdapter{ 
ArrayList<Model> currentArticle; 
ArrayList<Model> entireArticle; 
String selectedCategory="all";  //setting default category as "all" 
public ArticleAdapter(ArrayList<Model> categoryList){ 
    this.entireList=categoryList; 
    this.currentList=this.entireList; 
} 
//create updateCategory in adapter 
/*call this method(updateCategory()) in you frgament/activity to update the adapter 
    according to you category that is selected in dialog 
*/ 
public void updateCategory(String category){ 
    this.currentArticle.clear(); 
    this.selectedCategory=category; 
    for(Model item: entireArticle){ 
     if(category.equals(item.getCategory())) 
     { 
      currentArticle.add(item); 
     } 
    } 
    notifyDataSetChanged(); 
} 
........ 
........ 
@Override 
public View getView(int _position, View _convertView, ViewGroup _parent) { 
View view = _convertView; 
ViewHolder viewHolder; 

if (view == null) { 
    LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    view = inflater.inflate(R.layout.article_list_row, null); 
    viewHolder = new ViewHolder(); 
    viewHolder.article_icon = (ImageView) view.findViewById(R.id.article_category_icon); 
    viewHolder.articleTitle = (TextView) view.findViewById(R.id.article_title); 
    viewHolder.articleCategory = (TextView) view.findViewById(R.id.article_category); 
    viewHolder.articleDate = (TextView) view.findViewById(R.id.article_date); 
    viewHolder.articleAuthor = (TextView) view.findViewById(R.id.article_author); 
    view.setTag(viewHolder); 
} else { 
    viewHolder = (ViewHolder) _convertView.getTag(); 
} 

//Find the article to work with 
Article currentArticle = articles.get(_position); 
//just remove if condition because already you have filtered article by category in currentArticle 
//fill the Article_View 
switch (currentArticle.getCategory()) { 
    case "Kernel": 
     viewHolder.article_icon.setImageResource(R.drawable.ic_list_letter_k); 
     break; 
    case "Security": 
     viewHolder.article_icon.setImageResource(R.drawable.ic_list_letter_s); 
     break; 
     default: 
      viewHolder.article_icon.setImageResource(R.drawable.ic_list_letter_s); 

    } 
    viewHolder.articleTitle.setText(currentArticle.getTitle()); 
    viewHolder.articleCategory.setText(currentArticle.getCategory()); 
    viewHolder.articleDate.setText(currentArticle.getDate()); 
    viewHolder.articleAuthor.setText(currentArticle.getAuthor()); 
    return view; 
} 
} 

Tun Sie dies in Ihrer Aktivität/Fragment, die tha ArticleAdapter Modifikation in onSelectedOption hat() -Methode in Ihrer Aktivität/Fragment

@Override 
public void onSelectedOption() { 
selectedCategory = dialog.getSelectedCategory(); 
preSelectedValue = dialog.getSelectedIndex(); 

Log.i(TAG, "selectedCategory : " +selectedCategory); 
article_list_adapter.updateSelectedCategory(selectedCategory); 
Log.i(TAG, "adapter Category : " +article_list_adapter.getSelectedCategory()); 

/* 
    call updateCategory() instead of notifyDataSetChanged() 
    updateCategory() will update your adapter 
*/ 
//article_list_adapter.notifyDataSetChanged(); 
article_list_adapter.updateCategory(selectedCategory); 

}

Problem in Ihrem Code ist Sie versuchen, den Adapter mithilfe von notifyDataSetChanged zu aktualisieren, ohne Ihre Liste zu aktualisieren.

notifyDataSetChanged() funktioniert, wenn ein Update im Adaptermodell nicht in einer Variablen in Ihrem Adapter vorhanden ist.finden Sie in diesem how notifyDataSetChanged works in listView

EDIT: Änderungen in Adapterklasse

class Adapter{ 
    ArrayList entireArticle; 
    ArrayList currentArticle; 

    public Adapter(Context context,ArrayList list){ 
     this.entireArticle=new ArrayList(); 
     this.currentArticle=new ArrayList(); 

     entireArticle.addAll(list);  
     currentArticle.addAll(list); 
    } 

    public void updateCategory(String category){ 
    this.currentArticle.clear(); 
    this.selectedCategory=category; 
    if(category.equals("All")){ // add all article from entrieArticle if category=="all" 
     this.currentArticle.addAll(entireArticle); 
    }else{ //otherwise filter the article 
     for(Model item: entireArticle){ 
      if(category.equals(item.getCategory())) 
      { 
      currentArticle.add(item); 
      } 
    } 
    } 
    notifyDataSetChanged(); 
} 
............... 
................. 
} 

tun dies Änderungen in Ihrem Adapter-Klasse und es wird funktionieren ich dies überprüft haben.

Ich hoffe, das wird Ihnen helfen.

+0

Es macht Sinn, aber jetzt, wenn es mir nichts in der Liste zeigt :( –

+0

in t Die updateCategory, die du geschrieben hast, ich habe die if-Anweisung folgendermaßen geändert: if (category.toUpperCase(). equals (article.getCategory(). toUpperCase()) || category.equals ("All")) um sicherzustellen, dass bei Auswahl von Alle alles angezeigt wird. aber es ist nicht –

+0

jetzt verwenden Sie falsche Bedingung. immer "EIN" ungleich "eins". Sie werden also automatisch eine andere Bedingung wählen, d. h. category.equals (all). Aus diesem Grund erhalten Sie keinen Artikel der ausgewählten Kategorie. und ich wundere mich auch, warum Ihre Kategorie = "alle" in If-Anweisung überprüft. Es gibt nur eine Kategorie wird an den Adapter rechts gesendet, dann ist es redundant. – Madhan