代码之家  ›  专栏  ›  技术社区  ›  Bite code

如何提高(感知)Android下复杂ListView创建的速度?

  •  1
  • Bite code  · 技术社区  · 16 年前

    我有一个应用程序使用ListView作为主屏幕。每一行根据数据显示一些文本、一个复选框和图像,由于使用标准的ListAdapter无法做到这一点,所以我创建了自己的。

    每次列表数据发生更改(添加/删除行、检查提示、导航等),我都会使用以下方法刷新列表显示:

    public void refreshList()
    {
        // fetch the new items
        ItemDbHelper items = new ItemDbHelper(this);
        Cursor item_cursor = items.fetchItemForCurrentView(this.current_context_filter);
    
        // do not use "start managing cursor" here or resume() won't work
        // anymore since the cursor will be closed despite we still need it
    
        // set the welcome message if no items to display
        if (item_cursor.getCount() == 0)
        {
            TextView message = (TextView) this.findViewById(R.id.home_message);
            message.setVisibility(View.VISIBLE);
        }
    
        ListView list = this.task_list;
        ItemListAdapter item_cursor_adater = (ItemListAdapter) list.getAdapter();
    
        // close the old cursor manually and replace it with the new one
        item_cursor_adater.getCursor().close();
        item_cursor_adater.changeCursor(item_cursor);
        // reset some cache data in the adapter
        item_cursor_adater.reset();
        // tell the list to refresh
        item_cursor_adater.notifyDataSetChanged();
    
        // to easy navigation, we set the focus the last selected item
        // set the last modified item as selected
        int selected_index = this.getItemPositionFromId(list, 
                                                        this.getCurrentContextFilter()
                                                            .getSelectedTaskId());
    
        list.setSelection(selected_index);
    }
    

    一些事实:

    • items.fetchItemForCurrentView() 触发非常严重的SQL查询

    • this.getItemPositionFromId() 逐行循环整个ListView以查找具有给定ID的行的索引。

    • 这个 item_cursor_adapter 扩展SimpleCursorAdapter和重写

      公共视图getview(int position、view convertview、viewgroup parent)

    这是一个相当沉重的方法。

    在典型的应用程序用例中,经常根据用户需求调用此方法,并等待一秒钟以刷新屏幕,从而降低用户体验。

    你对如何改进这个有什么建议吗?

    一些想法:

    • 使用线程加载数据。但是,之后,如何补充列表呢?如何使它在屏幕上看起来不受干扰?
    • 重用一些对象/使用一些我没想到的缓存。
    • 找到一种更新列表而不重新加载所有内容的方法
    • 更改光标适配器的实现。可能扩展一个更有效的父级,或者使用比GetView更好的东西?
    2 回复  |  直到 12 年前
        1
  •  5
  •   CommonsWare    16 年前

    你可以去掉所有的代码然后打电话 requery() Cursor . 顾名思义,它重新运行生成 光标 首先。这将获取数据更改并通知列表适配器这些更改。您的列表适配器将为任何可见行更新屏幕。

    对于一个 SimpleCursorAdapter ,或者重写 newView() / bindView() 或使用 ViewBinder 或使用 setViewValue() 和亲属,如 documentation . 你 可以 重写 getView() 但是你必须自己做垃圾回收工作。

        2
  •  0
  •   kranti    12 年前

    使用光标适配器而不是基适配器和数组适配器