CursorAdapter:从未调用过newView和bindView

时间:2018-07-06 00:14:05

标签: android android-cursoradapter

我正在尝试创建一个ListView,应该使用从SQLiteDatabase检索到的数据来填充。为此,我创建了一个自ResourceCursorAdapter继承的自定义适配器。 在主活动中,我有一个按钮,单击该按钮会创建一个片段,该片段应显示我的列表。但是,尽管似乎我已将适配器正确设置为ListView(调用了构造函数)newView,却从未调用过bindView。 我已经按照以下小教程创建了适配器:https://github.com/codepath/android_guides/wiki/Populating-a-ListView-with-a-CursorAdapter

我想念什么?

根据我的活动:

loadSnapshotsButton.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // some static extra items
        final MatrixCursor extras = new MatrixCursor(new String[]{
                SettingsContract.PixelSnapshotEntries._ID,
                SettingsContract.PixelSnapshotEntries.SNAPSHOT_NAME,
                SettingsContract.PixelSnapshotEntries.SNAPSHOT_SIZE
        });
        extras.addRow(new String[]{"-1", "export snapshots set...", null});
        extras.addRow(new String[]{"-2", "load snapshots set...", null});
        final String[] settingsFields = new String[]{
                SettingsContract.PixelSnapshotEntries._ID,
                SettingsContract.PixelSnapshotEntries.SNAPSHOT_NAME,
                SettingsContract.PixelSnapshotEntries.SNAPSHOT_SIZE
        };
        final Cursor cursor = mDb.query(
                SettingsContract.PixelSnapshotEntries.TABLE_NAME,
                settingsFields,
                null, null, null, null, null
        );
        final Cursor[] cursors = {cursor, extras};
        final MergeCursor mergedCursor = new MergeCursor(cursors);
        Log.d(TAG, "num results: " + mergedCursor.getCount());

        SelectSnapshotFragment snapshotSelect = new SelectSnapshotFragment();
        fragmentManager
                .beginTransaction()
                .add(R.id.camera_preview, snapshotSelect, "snapshot select")
                .commit();
        // creation of the list view is happening in the fragment
        // in order to avoid asyncronicity issues
        snapshotSelect.setCursor(mergedCursor);
        cursor.close();
        extras.close();
    }

onCreateView来自片段:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.snapshots_list, container, false);
    final ListView snapshotsListView = (ListView) view.findViewById(R.id.snapshots_list);
    final SnapshotSelectAdapter adapter = new SnapshotSelectAdapter(getActivity(), R.layout.snapshots_item, mCursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    snapshotsListView.setAdapter(adapter);
    // check for the adapter to be set properly - OK
    Log.d(TAG, "snapshots list view: " + snapshotsListView.getAdapter());
    mCursor.close();
    container.addView(view);
    return super.onCreateView(inflater, container, savedInstanceState);
}

我的自定义适配器:

public class SnapshotSelectAdapter extends ResourceCursorAdapter {
    final private static String TAG = "SnapshotSelectAdapter";
    private int mLayout;

    public SnapshotSelectAdapter(Context context, int layout, Cursor c, int flags) {
        super(context, layout, c, flags);
        // cursor holds the right number of items - OK
        Log.d(TAG, "cursor: " + c.getCount());
        mLayout = layout;
    }

    // never called
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(mLayout, parent, false);
    }

    // never called either
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        TextView row = (TextView) view.findViewById(R.id.snapshot_item);
        Log.d(TAG, "view: " + view + ", row: " + row);
        String text = cursor.getString(cursor.getColumnIndexOrThrow(SettingsContract.PixelSnapshotEntries.SNAPSHOT_NAME)) + " (" +
            String.valueOf(cursor.getInt(cursor.getColumnIndexOrThrow(SettingsContract.PixelSnapshotEntries.SNAPSHOT_SIZE))) + ")";
        row.setText(text);
    }

snapshots_list.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/snapshots_selection"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:background="@color/colorDarkTransparentBackground"
          android:animateLayoutChanges="true"
          android:orientation="vertical">

    <ListView
        android:id="@+id/snapshots_list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="20dp"
        android:paddingEnd="20dp"
        android:paddingLeft="20dp"
        android:paddingRight="20dp"
        android:paddingStart="20dp"
        android:paddingTop="5dp"/>

</LinearLayout>

snapshots_item.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingBottom="15dp"
        android:paddingTop="15dp"
        android:textSize="20sp"
        android:id="@+id/snapshot_item" />

2 个答案:

答案 0 :(得分:1)

我在您的片段中的onCreateView中看到了问题。

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.snapshots_list, container, false);
    final ListView snapshotsListView = (ListView) view.findViewById(R.id.snapshots_list);
    final SnapshotSelectAdapter adapter = new SnapshotSelectAdapter(getActivity(), R.layout.snapshots_item, mCursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    snapshotsListView.setAdapter(adapter);
    // check for the adapter to be set properly - OK
    Log.d(TAG, "snapshots list view: " + snapshotsListView.getAdapter());
    return view
}

您应该从此方法返回视图,无需手动附加到容器。

在适配器尚未读取和初始化列表行之前,

请勿关闭onCreateView中的光标。 请签出this answer,以了解在何处关闭光标。

可能是在onStop()方法中发生了光标关闭,然后您

最后,我建议不要使用过时的教程。

从现在开始,您可以使用RecyclerView而不是ListViewRoom来代替手动处理游标和cursorAdapters。

如果数据库中的列表很大,则可以使用Pagination库。 为此,我建议您查看Google I/O有关列表和分页的信息。

答案 1 :(得分:0)

经过一番挣扎,我认为我找到了解决方案。据我所知,问题出在我片段的onCreateView之内。我将视图明确附加到容器。删除该行newViewbindView后,按预期进行调用:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final ScrollView bg = (ScrollView) inflater.inflate(R.layout.settings_background_scroll, container, false);
    final View view = inflater.inflate(R.layout.snapshots_list, bg, false);
    final ListView snapshotsListView = (ListView) view.findViewById(R.id.snapshots_list);
    final SnapshotSelectAdapter adapter = new SnapshotSelectAdapter(getActivity(), R.layout.snapshots_item, mCursor, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    snapshotsListView.setAdapter(adapter);
    return view;
}