当用户到达底部时,动态地从JSON填充listview

时间:2014-06-08 07:03:20

标签: android android-listview android-json

我通过JSON填充ListView。我用this tutorial完成了它。

我遇到的唯一问题:我想在用户到达ListView的末尾时加载更多项目,我不想在开头加载100个项目。我想要显示10个项目,然后再显示10个项目。我怎么能这样做?

2 个答案:

答案 0 :(得分:5)

请按以下步骤操作: -
大多数代码都经过评论,因此您可以了解每个语句的作用。

将FooterView添加到ListView

页脚视图只不过是一段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);

现在是有趣的部分,检查我们是否一直向下并加载项目

Java实施

实际加载是在一个单独的线程(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();
        }
    }
});

实现Runnables来处理加载

加载由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项目旨在实现此目的。它表示现在退役了,没有列出任何解释或替换,但它运作得非常好。