我是Android的新手,也是StackOverflow的新手:)
我目前正在编写应用程序,它在ListView
中显示文章。
我的目标是,我想要ListView
中的搜索/过滤选项。
我创建了一个Fragment
,其中显示了输入的SearchView
和填充了文章的ListView
。
我的问题是,当我在SearchView
中输入一封信时,我的应用因IndexOutOfBounceException
而崩溃。
java.lang.IndexOutOfBoundsException: Invalid index 2, size is 2
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:62)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
at android.widget.ListView.onMeasure(ListView.java:1182)
at android.view.View.measure(View.java:17586)
我在我的ArticleAdapter
中创建了一个自定义过滤器,用于比较文章标题是否包含SearchView
的输入。
以下是适配器类的代码:
class Article_List_Adapter extends ArrayAdapter<Article> implements Filterable {
public static final String TAG = "List_Adapter Test";
public List<Article> articles;
CustomFilter filter;
public Article_List_Adapter(Context _c, int textViewResourceId, List<Article> articles) {
super(_c, textViewResourceId, articles);
this.articles = articles;
}
public class ViewHolder {
ImageView article_icon;
TextView articleTitle;
TextView articleCategory;
TextView articleDate;
TextView articleAuthor;
}
@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 = getItem(_position);
Article currentArticle = articles.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;
}
public Filter getFilter() {
if (filter == null) {
filter = new CustomFilter();
}
return filter;
}
class CustomFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence _constraint) {
FilterResults results = new FilterResults();
ArrayList<Article> article_list = (ArrayList<Article>) articles;
Log.e(TAG, "articles size: "+article_list.size());
ArrayList<Article> tempList = new ArrayList<>();
if (_constraint != null && articles != null) {
for (final Article a : article_list) {
if (a.getTitle().toLowerCase().contains(_constraint.toString())) {
tempList.add(a);
}
}
Log.e(TAG, "tempList size: "+tempList.size());
results.values = tempList;
results.count = tempList.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
articles = (ArrayList<Article>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
这里是My Fragment,它显示了SearchView和ListView:
public class SearchFragment extends Fragment {
private ListView articleListView;
private List<Article> articles;
private SearchView inputSearch;
private ArrayAdapter<Article> article_list_adapter;
public SearchFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_search, container, false);
articles = MainActivity.getInstance().getArticleList();
articleListView = (ListView) view.findViewById(R.id.search_list_view);
inputSearch = (SearchView) view.findViewById(R.id.inputSearch);
//Create and Set Adapter for ListView
article_list_adapter = new Article_List_Adapter(getActivity(), R.layout.article_list_row, articles);
articleListView.setAdapter(article_list_adapter);
//Set Property for SearchView
inputSearch.setQueryHint("Search");
//SEARCH
inputSearch.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String query) {
article_list_adapter.getFilter().filter(query);
return false;
}
});
return view;
}
}
我希望我没有忘记任何事情。 THX!
P.S。这是我的第一篇文章
答案 0 :(得分:0)
这里有错误。
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
articles = (ArrayList<Article>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
您的类从基类扩展,并将List
放在基础构造函数中,因此您更新articles
引用基类中的引用。因此,ListView
获取放在基类构造函数中的List
的项目数
要解决此问题,您需要覆盖getItemsCount
方法(请参阅Android文档中的正确方法名称。