我对listview的滚动有问题。我有一个类:
private int itemsPerPage = 6;
private int count = 0;
private boolean loadingMore = false;
private ArrayList<Item> item;
private ListItemAdapter adapter;
View footerView;
private JSONArray array;
private String json;
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.menu);
lvListItem = (ListView) findViewById(R.id.lvListItem);
item = new ArrayList<Item>();
footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.list_footer, null, false);
json = new JSONParse()
.getData("....");
array = new JSONArray(json);
load();
adapter = new ListItemAdapter(this, 0, item);
lvListItem.addFooterView(footerView);
lvListItem.setAdapter(adapter);
lvListItem.setOnScrollListener(new OnScrollListener() {
public void onScrollStateChanged(AbsListView view, int scrollState) {
// TODO Auto-generated method stub
}
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
// TODO Auto-generated method stub
int lastInScreen = firstVisibleItem + visibleItemCount;
// is the bottom item visible & not loading more already ? Load
// more !
if ((lastInScreen == totalItemCount) && !(loadingMore)) {
Thread thread = new Thread(null, loadData);
thread.start();
}
}
});
}
public void load(){
for (int i = 0; i < itemsPerPage; i++) {
if (count == array.length()) {
lvListItem.removeFooterView(footerView);
break;
}
/*****Code to load data*******/
}
}
private Runnable loadData = new Runnable() {
@Override
public void run() {
loadingMore = true;
item = new ArrayList<Item>();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
load();
runOnUiThread(returnRes);
}
};
private Runnable returnRes = new Runnable() {
@Override
public void run() {
if (item != null && item.size() > 0) {
for (int i = 0; i < item.size(); i++)
adapter.add(item.get(i));
}
if (count == array.length())
lvListItem.removeFooterView(footerView);
adapter.notifyDataSetChanged();
// Done loading more.
loadingMore = false;
}
};
如果我只使用 load(),它会运行并且listview显示数据正常。但是当我滚动listview时,它会抛出错误:
D/AndroidRuntime(1635): Shutting down VM W/dalvikvm(1635): threadid=1: thread exiting with uncaught exception (group=0x40a13300) E/AndroidRuntime(1635): FATAL EXCEPTION: main E/AndroidRuntime(1635): java.lang.IndexOutOfBoundsException: Invalid index 6, size is 6 E/AndroidRuntime(1635): at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:251) E/AndroidRuntime(1635): at java.util.ArrayList.get(ArrayList.java:304)
我需要帮助
答案 0 :(得分:0)
看起来你的数组只有6个元素,你试图访问索引为6的元素,这实际上是第7个元素所以
更改
itemsPerPage = 5;`
答案 1 :(得分:0)
您的代码根本不是线程安全的。您正在从多个线程访问共享数据而不进行任何类型的锁定。在item
runnable(在主线程上运行)中读取您的resultRes
数组时,您的private final Object monitor = new Object(); // an ivar in your Activity
数组可能正在重新初始化,这将导致看似无法超出范围的异常
创建一个用作互斥锁的对象:
item
然后,当访问共享数据(例如loadingMore
和synchronized(monitor) {
item = new ArrayList<Item>();
}
synchronized(monitor) {
if (item != null && item.size() > 0) {
for (int i = 0; i < item.size(); i++)
adapter.add(item.get(i));
}
}
synchronized(monitor) {
if ((lastInScreen == totalItemCount) && !(loadingMore)) {
Thread thread = new Thread(null, loadData);
thread.start(); // will exit critical section before new thread execution begins
}
}
)时,创建一个关键部分,例如:
{{1}}
等等。我会把它作为练习让你弄清楚其余的锁定应该在哪里完成。