Android:无限滚动 - ListView 和 Cursor

发布于 2024-11-18 07:25:33 字数 2302 浏览 3 评论 0原文

我有大约 15,000 行的数据库表,我想将其显示在列表视图中。我想显示前 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 但列表未更新,我缺少什么?

I have DB table with ~15,000 rows which I want to display in the listview. I want to display first 100 and when the user scrolls down to the last item the next 100 should be loaded (an so on...). I have implemented on OnScrollListener() which calls AsyncTask responsible for loading more items. The problem I've got is that my SimpleCursorAdapter is not updated after more rows are added to the cursor. I have tried adapter.notifyDataSetChanged(); but that doesn't do anything.

This is the list listener:

    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) {}
    });

This is my AsyncTask class:

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;
    }
}

New rows are added to resultCursor but the list is not updated, what am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苦笑流年记忆 2024-11-25 07:25:33

我将发布一个代码,我用它在滚动事件中每个记录填充 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) 是我用来设置 totalHistoryItemCount & 的值的方法。 checkInCheckOutHistoryList

希望这会有所帮助。

I will post a code which I have used to populated 10 records each on scroll event.

  /**
     * 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) is the method I have used to set the values for totalHistoryItemCount & checkInCheckOutHistoryList.

Hope this would help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文