创建包含超过100个项目(确切地说是111个)并部署应用程序的列表视图后,它会按预期运行,但只要我滚动列表,应用程序就会崩溃并返回ArrayIndexOutOfBoundsException
。我真的不明白为什么长度和指数正在回归' 19'有谁知道为什么要显示19?需要做些什么来解决这个问题?
java.lang.ArrayIndexOutOfBoundsException:length = 19;指数= 19 在com.helloapps.helloworldapp.adapters.OrangeListAdapter.getPositionForSection(OrangeListAdapter.java:160)
XML
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:choiceMode="singleChoice"
android:fastScrollEnabled="true"
android:scrollbarStyle="outsideInset"/>
爪哇
public class OrangeListAdapter extends BaseAdapter implements Filterable, SectionIndexer {
private List<Orange> mData;
private List<Orange> mFilteredData;
private LayoutInflater mInflater;
private ItemFilter mFilter;
private Object[] mSections;
private int[] mSectionsIndexedByPosition;
private int[] mPositionsIndexedBySection;
public OrangeListAdapter (List<Orange> data, Context context) {
mData = data;
mFilteredData = new ArrayList(mData);
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
setupSections();
}
@Override
public int getCount() {
return mFilteredData.size();
}
@Override
public Orange getItem(int position) {
return mFilteredData.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) {
convertView = mInflater.inflate(R.layout.list_item_dualline, parent, false);
holder = new ViewHolder();
holder.title = (TextView) convertView.findViewById(R.id.item_name);
holder.description = (TextView) convertView.findViewById(R.id.item_description);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
Orange orange = getItem(position);
holder.title.setText(orange.getName());
holder.description.setText(orange.getDescrption());
if (orange.isSelected()) {
convertView.setBackgroundColor(Color.parseColor("#FF6600"));
holder.title.setTextColor(Color.parseColor("#FFFFFF"));
holder.description.setTextColor(Color.parseColor("#FFFFFF"));
} else {
convertView.setBackgroundColor(Color.TRANSPARENT);
holder.title.setTextColor(Color.parseColor("#FFFFFF"));
holder.description.setTextColor(Color.parseColor("#B5B5B5"));
}
holder.title.setText(mFilteredData.get(position).getStation());
holder.description.setText(mFilteredData.get(position).getZone());
return convertView;
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemFilter();
}
return mFilter;
}
/**
* View holder
*/
static class ViewHolder {
private TextView title;
private TextView description;
}
private class ItemFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
if (TextUtils.isEmpty(constraint)) {
results.count = mData.size();
results.values = new ArrayList(mData);
} else {
//Create a new list to filter on
List<Orange> resultList = new ArrayList<Orange>();
for (Orange str : mData) {
if (str.getStation().toLowerCase().contains(constraint.toString().toLowerCase())) {
resultList.add(str);
}
}
results.count = resultList.size();
results.values = resultList;
}
return results;
}
/**
* Runs on ui thread
* @param constraint the constraint used for the result
* @param results the results to display
*/
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count == 0) {
mFilteredData.clear();
notifyDataSetInvalidated();
} else {
mFilteredData = (ArrayList<Orange>)results.values;
notifyDataSetChanged();
}
setupSections();
}
}
@Override
public int getPositionForSection(int section) {
return mPositionsIndexedBySection[section];
}
@Override
public int getSectionForPosition(int position) {
return mSectionsIndexedByPosition[position];
}
@Override
public Object[] getSections() {
return mSections;
}
private void setupSections() {
String initial = "\0";
List<String> sections = new ArrayList<String>();
mSectionsIndexedByPosition = new int[mFilteredData.size()];
mPositionsIndexedBySection = new int[mFilteredData.size()];
int section = 0;
for (int pos = 0; pos < mFilteredData.size(); pos++) {
Orange orange = mFilteredData.get(pos);
if (initial.charAt(0) != orange.getName().charAt(0)) {
initial = orange.getName().substring(0, 1);
section = sections.size();
sections.add(initial);
mPositionsIndexedBySection[section] = pos;
mSectionsIndexedByPosition[pos] = section;
} else {
mSectionsIndexedByPosition[pos] = section;
}
}
mSections = sections.toArray();
mPositionsIndexedBySection = Arrays.copyOf(mPositionsIndexedBySection, mSections.length);
}
}
答案 0 :(得分:0)
您的数组声明只有19个位置,这意味着您可以访问最大索引18,因为数组索引以0开头,但在上面的代码中您正在访问第19个索引,那么它会抱怨您的索引超出范围那是18岁。
这条线对我来说有点问题:
mPositionsIndexedBySection = Arrays.copyOf(mPositionsIndexedBySection, mSections.length);
**To solve the problem**
:确保根据大小将数据放入数组中。如果数组的大小为n,即19,那么你应该只将元素放到n-1索引,即18。
答案 1 :(得分:0)
快速滚动条仅从SectionIndexer.getSections()
读取您的部分一次,之后不会更改。
因此,当您的第一个列表包含超过19个部分时,似乎会出现问题,然后重新加载一个列表,您希望将部分数量减少到少于19,这也会减少mPositionsIndexedBySection
的大小。
因为快速滚动条仍记得旧版块,并尝试获取第19部分的位置,所以会发生错误。
要解决此问题,请使用包含所有可用部分的固定数量的部分,仅在数据更改时更改mPositionsIndexedBySection
和mSectionsIndexedByPosition
。
修改:
请查看以下链接,了解如何正确实施SectionIndexer
http://androidopentutorials.com/android-listview-fastscroll/
http://responsiveandroid.com/2013/04/13/android-sectionindexer-with-alphabet.html