我正在尝试创建一个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" />
答案 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
而不是ListView
和Room
来代替手动处理游标和cursorAdapters。
如果数据库中的列表很大,则可以使用Pagination
库。
为此,我建议您查看Google I/O有关列表和分页的信息。
答案 1 :(得分:0)
经过一番挣扎,我认为我找到了解决方案。据我所知,问题出在我片段的onCreateView
之内。我将视图明确附加到容器。删除该行newView
和bindView
后,按预期进行调用:
@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;
}