我遇到了以下问题。
我有一个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;
答案 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();
}
...............
.................
}
在您的适配器类中执行此更改,它将起作用我已经检查过。
我希望这会对你有所帮助。