You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SimpleCursorLoader在ListView中显示元素

使用SimpleCursorLoader在Fragment的ListView中显示SQLite数据的实现指南

嘿,我来帮你搞定用SimpleCursorLoader在Fragment的ListView里展示SQLite数据的事儿。这玩意儿能帮你异步加载数据,避免主线程阻塞,让界面体验更流畅。咱们一步步来:

第一步:让Fragment实现LoaderCallbacks接口

你的Tab3Fragment需要实现LoaderManager.LoaderCallbacks<Cursor>接口,这样才能和Loader框架正常交互。修改类定义:

public class Tab3Fragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
    // 后续变量定义放在这里
}

第二步:调整DBHandler的初始化时机

注意哦,getContext()在Fragment的onCreateView之前可能是null的,别在成员变量里直接初始化dbHandler,把它移到onCreateView或者onViewCreated里更稳妥:

private DBHandler dbHandler;
private ListView listView;
private SimpleCursorAdapter adapter;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.tab3_frag, container, false);
    // 初始化DBHandler
    dbHandler = new DBHandler(getContext(), null, null, 4);
    // 找到布局里的ListView(替换成你实际的ID)
    listView = view.findViewById(R.id.list_view_students);
    return view;
}

第三步:初始化CursorAdapter并启动Loader

在onViewCreated方法里配置列表适配器,然后启动Loader:

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    
    // 定义要从Cursor取的列,以及对应列表项布局里的控件ID
    String[] fromColumns = {
        Contract.Student_Table.STUDENTS_COLUMN_NAME,
        Contract.Student_Table.STUDENTS_COLUMN_AGE
    };
    int[] toViews = {
        R.id.tv_student_name, // 替换成你列表项里的TextView ID
        R.id.tv_student_age
    };
    
    // 初始化SimpleCursorAdapter,初始Cursor传null,Loader会帮我们加载数据
    adapter = new SimpleCursorAdapter(
        getContext(),
        R.layout.item_student, // 替换成你的列表项布局文件
        null,
        fromColumns,
        toViews,
        0
    );
    listView.setAdapter(adapter);
    
    // 启动Loader,第一个参数是唯一的Loader ID,随便设个数字就行
    getLoaderManager().initLoader(1, null, this);
}

第四步:实现LoaderCallbacks的三个核心方法

这部分是Loader的核心逻辑,负责创建Loader、处理加载完成的数据、重置Loader:

onCreateLoader:创建SimpleCursorLoader并定义查询逻辑

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    // 必须包含_ID列!CursorAdapter要求Cursor必须有这个列,不然会报错
    String[] projection = {
        Contract.Student_Table._ID,
        Contract.Student_Table.STUDENTS_COLUMN_NAME,
        Contract.Student_Table.STUDENTS_COLUMN_AGE
    };
    // 可以按需添加查询条件、排序规则
    String sortOrder = Contract.Student_Table.STUDENTS_COLUMN_NAME + " ASC";
    
    return new SimpleCursorLoader(getContext()) {
        @Override
        public Cursor loadInBackground() {
            // 在后台线程执行SQL查询,避免阻塞主线程
            return dbHandler.getReadableDatabase().query(
                Contract.Student_Table.TABLE_NAME,
                projection,
                null, // 查询条件,按需设置
                null, // 条件参数
                null,
                null,
                sortOrder
            );
        }
    };
}

onLoadFinished:加载完成后更新列表数据

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // 把加载好的Cursor交给适配器,列表会自动刷新
    adapter.swapCursor(data);
}

onLoaderReset:重置Loader时清理Cursor

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    // 清空适配器的Cursor,避免内存泄漏
    adapter.swapCursor(null);
}

额外提示:数据更新后刷新列表

当你对SQLite数据库做了增删改操作后,只需要调用下面的代码就能让Loader重新加载数据,自动更新列表:

getLoaderManager().restartLoader(1, null, this);

内容的提问来源于stack exchange,提问作者Jon Goe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:44:03