从对话框窗口中选择项目后更新ListView

时间:2016-06-30 17:02:04

标签: android listview filter dialog

我遇到了以下问题。

我有一个ListView,它显示了不同类别的文章。 当我从对话框窗口中选择一个类别并按下PositiveButton“确定”时,我想更新我的ListView,它现在只列出在对话窗口中选择的类别中的文章。

我在DialogFragment中创建了一个接口,它是一个从Dialog获取值的回调。

这是班级:

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

}

在我的SearchFragment类中,我显示List并从SelectFilterDialog片段实现接口。 在方法中,我按下确定按钮后更新selectedCategory,然后使用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);
}   

在我的适配器中,我在updateCategory中收到类别,并使用正确类别的文章填充当前文章列表。 这很好用。 之后我调用NotifyDataSetChanged来更新视图。

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

但是在getView中它抛出了一个IndexOutOfBounce异常。 从对话框中选择一个类别,例如“内核”后,它只将我的3个内核类别添加到当前文章列表中,这很好。 但是在getView语句中:

Article currentArticle = currentArticles.get(_position);    

它指向索引3,但列表中只有3个元素。

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)    
你能帮帮我吗? :)

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;

1 个答案:

答案 0 :(得分:0)

在适配器类中执行此操作 为AllCategoryArticle创建两个List,为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;
 }
}

在包含ArticleAdapter的Activity / Fragment中执行此操作 修改活动/片段中的onSelectedOption()方法

@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);

}

代码中的问题 您尝试使用notifyDataSetChanged更新适配器而不更新列表。

当适配器模型中的更新不在适配器中的任何变量中时,

notifyDataSetChanged()将起作用。请参阅此how notifyDataSetChanged works in listView

编辑:适配器类的更改

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

在您的适配器类中执行此更改,它将起作用我已经检查过。

我希望这会对你有所帮助。