我通过JSON填充ListView
。我用this tutorial完成了它。
我遇到的唯一问题:我想在用户到达ListView
的末尾时加载更多项目,我不想在开头加载100个项目。我想要显示10个项目,然后再显示10个项目。我怎么能这样做?
答案 0 :(得分:5)
请按以下步骤操作: -
大多数代码都经过评论,因此您可以了解每个语句的作用。
页脚视图只不过是一段XML,它定义了listview的页脚的外观。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:gravity="center_horizontal"
android:padding="3dp"
android:layout_height="fill_parent">
<TextView
android:id="@id/android:empty"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:gravity="center"
android:padding="5dp"
android:text="Loading more days..."/>
</LinearLayout>
它只是一个简单的文本视图,带有用于演示目的的消息。但你可以在这里放任何东西: - )
将视图添加到ListView并不难。您唯一需要注意的是,将它放在将适配器添加到View的行上方!我们将使用此代码将其添加到ListView:addFooterView(View)
//add the footer before adding the adapter, else the footer will not load!
View footerView = ((LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listfooter, null, false);
this.getListView().addFooterView(footerView);
现在是有趣的部分,检查我们是否一直向下并加载项目
实际加载是在一个单独的线程(Runnable)中完成的。这样我们就不会锁定主界面(GUI)。
//Here is where the magic happens
this.getListView().setOnScrollListener(new OnScrollListener(){
//useless here, skip!
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {}
//dumdumdum
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
//what is the bottom iten that is visible
int lastInScreen = firstVisibleItem + visibleItemCount;
//is the bottom item visible & not loading more already ? Load more !
if((lastInScreen == totalItemCount) && !(loadingMore)){
Thread thread = new Thread(null, loadMoreListItems);
thread.start();
}
}
});
加载由2 Runnables
完成。调用第一个runnable loadMoreListItems
来获取数据,并在main(UI)线程上调用第二个runnable returnRes
来更新接口。要从第1个切换到第2个,我们使用名为runOnUiThread
以下是实现Runnables的代码,我尽可能地对代码进行了评论,以使其易于理解:
可运行以加载项目
private Runnable loadMoreListItems = new Runnable() {
@Override
public void run() {
//Set flag so we cant load new items 2 at the same time
loadingMore = true;
//Reset the array that holds the new items
myListItems = new ArrayList<String>();
//Simulate a delay, delete this on a production environment!
try { Thread.sleep(1000);
} catch (InterruptedException e) {}
//Get 15 new listitems
for (int i = 0; i < itemsPerPage; i++) {
//Fill the item with some bogus information
myListItems.add("Date: " + (d.get(Calendar.MONTH)+ 1) + "/" + d.get(Calendar.DATE) + "/" + d.get(Calendar.YEAR) );
// +1 day
d.add(Calendar.DATE, 1);
}
//Done! now continue on the UI thread
runOnUiThread(returnRes);
}
};
第二次运行: 由于我们无法从一个线程更新我们的UI,因此Runnable负责处理!
private Runnable returnRes = new Runnable() {
@Override
public void run() {
//Loop thru the new items and add them to the adapter
if(myListItems != null && myListItems.size() > 0){
for(int i=0;i < myListItems.size();i++)
adapter.add(myListItems.get(i));
}
//Update the Application title
setTitle("Neverending List with " + String.valueOf(adapter.getCount()) + " items");
//Tell to the adapter that changes have been made, this will cause the list to refresh
adapter.notifyDataSetChanged();
//Done loading more.
loadingMore = false;
}
};
答案 1 :(得分:1)
CommonsWare EndlessAdapter项目旨在实现此目的。它表示现在退役了,没有列出任何解释或替换,但它运作得非常好。