Android:无限滚动 - ListView 和 Cursor

标签 android listview android-cursor simplecursoradapter

我有大约 15,000 行的数据库表,我想将其显示在 ListView 中。我想显示前 100 个,当用户向下滚动到最后一个项目时,应该加载下一个 100 个(依此类推......)。我已经在 OnScrollListener() 上实现,它调用负责加载更多项目的 AsyncTask。我遇到的问题是,在将更多行添加到游标后,我的 SimpleCursorAdapter 没有更新。我试过 adapter.notifyDataSetChanged();但这没有任何作用。

这是列表监听器:

    myListView.setOnScrollListener(new OnScrollListener(){
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            int lastInScreen = firstVisibleItem + visibleItemCount;
            if(resultCursor != null){
                if(lastInScreen == totalItemCount && isLoadingMore == false){
                    isLoadingMore = true;
                    loadedPage ++;
                    new LoadBooks().execute();
                }
            }
        }
        public void onScrollStateChanged(AbsListView view, int scrollState) {}
    });


这是我的 AsyncTask 类:

private class LoadBooks extends AsyncTask<String, Void, Void> {
    private final ProgressDialog dialog = new ProgressDialog(FullIndex.this);

    @Override
    protected void onPreExecute() {
       this.dialog.setMessage("Loading books...");
       this.dialog.show();
    }

    @Override
    protected Void doInBackground(String... arg0) {
        try{
            resultCursor = dbHelper.fetchBooks(0, loadedPage * LIMIT_RESULTS);
        }catch(Exception e){
            e.printStackTrace();
        }
        return null;
    }
    @Override
    protected void onPostExecute(final Void unused){
        if(resultCursor != null){
            if(adapter == null){
                startManagingCursor(resultCursor);
                String[] from = new String[]{"name"};
                int[] to = new int[]{R.id.book_item_tbx};
                getListView().setTranscriptMode(ListView.TRANSCRIPT_MODE_NORMAL);
                adapter = new SimpleCursorAdapter(FullIndex.this, R.layout.book_item, resultCursor, from, to);
                setListAdapter(adp);
            }else{
                adapter.notifyDataSetChanged();
            }
        }
        if(dialog != null && dialog.isShowing()){
            dialog.dismiss();
        }
        isLoadingMore = false;
    }
}


新行已添加到 resultCursor 但列表未更新,我错过了什么?

最佳答案

我将发布一个代码,该代码用于在滚动事件中每条记录填充 10 条记录。

  /**
     * Called when the activity is first created.
     * 
     * @param savedInstanceState
     *            the saved instance state
     */
    @Override
    protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.view_checkin_checkout_history);

             Thread thread = new Thread() {

            public void run() {

                       synchronized (this) {
                    fetchHistory(0);

                    handler.post(new Runnable() {
                        public void run() {
                            pd.dismiss();

                            displayUI();
                        };
                    });
                }
            }
        };

        thread.start();
         }

       /**
     * Display the check in check out history list.
     */
    private void displayUI() {
        if ((checkInCheckOutHistoryList != null)
                && (checkInCheckOutHistoryList.size() > 0)) {
            historyArrayList = new ArrayList<HashMap<String, String>>();

            histroyListAdapter = new SimpleAdapter(
                    ViewCheckInCheckOutHistory.this, historyArrayList,
                    R.layout.multi_colummn_list_text_style_small, new String[] {
                            "assetTag", "gif" , "action", "actionTime"},
                    new int[] { R.id.list_content_column1,
                            R.id.list_content_imagecolumn,
                            R.id.list_content_column3,
                            R.id.list_content_column4});

            // To add more items to list view on scroll event.
            historyListView.setOnScrollListener(new OnScrollListener() {

                @Override
                public void onScrollStateChanged(AbsListView view,
                        int scrollState) {
                }

                @Override
                public void onScroll(AbsListView view, int firstVisibleItem,
                        int visibleItemCount, int totalItemCount) {

                    int lastInScreen = firstVisibleItem + visibleItemCount;

                    if ((lastInScreen == totalItemCount) && !(loadingMore) && (lastInScreen < totalHistoryItemCount)) {

                        if (!firstInstance) {
                            openSlider();                           
                        }                           

                        fetchHistory(lastInScreen);     

                        Thread thread = new Thread(null, loadMoreListItems);
                        thread.start();
                    }
                }
            });
                     }
                  }

// Runnable to load the items

    private Runnable loadMoreListItems = new Runnable() {

        @Override
        synchronized public void run() {
            // Set flag so we cant load new items 2 at the same time
            loadingMore = true;

            HashMap<String, String> historyObjectMap;

            for (CheckInCheckOutHistory checkOutHistoryObj : checkInCheckOutHistoryList) {
                historyObjectMap = new HashMap<String, String>();
                historyObjectMap.put("assetTag",
                        checkOutHistoryObj.getAssetTag());
                historyObjectMap.put("action", checkOutHistoryObj.getAction());
                historyObjectMap.put("actionTime",
                        checkOutHistoryObj.getActionDate());

                if (checkOutHistoryObj.getAction().equals("Checked out")) {
                    historyObjectMap.put("gif", R.drawable.radio_button_yellow
                            + "");
                } else {
                    historyObjectMap.put("gif", R.drawable.radio_button_green
                            + "");
                }

                historyArrayList.add(historyObjectMap);
            }

            runOnUiThread(returnRes);
        }
    };

    // Since we cant update our UI from a thread this Runnable takes care of
    // that!
    private Runnable returnRes = new Runnable() {
        @Override
        public void run() {

            // Add the new items to the adapter
            if (historyArrayList != null && historyArrayList.size() > 0) {
                histroyListAdapter.notifyDataSetChanged();
            }

            if (firstInstance) {
                historyListView.setAdapter(histroyListAdapter);
                firstInstance = false;
            }

            historyListLayout.setVisibility(View.VISIBLE);

            // Done loading more.
            loadingMore = false;

            if ((slidingDrawer.isOpened()) && (!loadingMore)) {

                handler.postDelayed(new Runnable() {

                    @Override
                    public void run() {
                        slidingDrawer.close();
                        slidingDrawer.setVisibility(View.GONE);
                    }
                }, 1000);

            }
        }
    };


fetchHistory(int count) 是我用来设置 totalHistoryItemCountcheckInCheckOutHistoryList 值的方法。

希望这会有所帮助。

关于Android:无限滚动 - ListView 和 Cursor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6573489/

相关文章:

android - 将对象arraylist转换为android中的游标

java - Android:即使数据库不为空,游标也始终返回 null

Android Volley Post 请求 - JsonArrayRequest 的解决方法

android - 我的 Android Studio 安装了什么版本的支持库

android - android :noHistory and android:finishOnTaskLaunch之间的关系

c# - 动画wpf列表框的选定项目

android - 使用 CursorLoader 查询专辑中的歌曲

android - 为什么 android.content.ContentResolver.delete 返回一个整数?

android - 向左滑动删除在可扩展高度 ListView 中不起作用

android - 如何在回到上一个ListView的同时保持ListView的位置?