我正在尝试使LoaderManager列表向后兼容Android 2.1。列表加载正常但@ id / android:empty消息显示即使列表中有明显可见的项目。
我已经在StackOverflow上查看了一些使用setEmptyView()和setEmptyText()但无法使它们工作的解决方案。
以下是ListFragment的代码。我一直在组合各种http://www.vogella.com/教程的代码。
package com.example.contentprov;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.example.contentprov.data.MyTodoContentProvider;
import com.example.contentprov.data.TodoTable;
/*
* TodosOverviewActivity displays the existing todo items
* in a list
*
* You can create new ones via the ActionBar entry "Insert"
* You can delete existing ones via a long press on the item
*/
public class TodoOverviewFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {
private SimpleCursorAdapter adapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setContentView(R.layout.todo_list);
fillData();
}
// Opens the second activity if an entry is clicked
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(getActivity(), TodoDetailActivity.class);
Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
startActivity(i);
}
private void fillData() {
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { TodoTable.COLUMN_SUMMARY };
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
getActivity().getSupportLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(getActivity(), R.layout.todo_row, null, from,
to, 0);
setListAdapter(adapter);
}
// Creates a new loader after the initLoader () call
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { TodoTable.COLUMN_ID, TodoTable.COLUMN_SUMMARY };
CursorLoader cursorLoader = new CursorLoader(getActivity(),
MyTodoContentProvider.CONTENT_URI, projection, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}
@Override
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
Intent i = new Intent(getActivity(), TodoDetailActivity.class);
Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
startActivity(i);
}
}
以下是列表的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
<TextView
android:id="@id/android:empty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/no_todos" />
</LinearLayout>
编辑:解决方案是结合Eluvatar和dymmeh的答案。这是ListFragment的新版本。
package com.example.contentprov;
import android.support.v4.app.ListFragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import com.example.contentprov.data.MyTodoContentProvider;
import com.example.contentprov.data.TodoTable;
/*
* TodosOverviewActivity displays the existing todo items
* in a list
*
* You can create new ones via the ActionBar entry "Insert"
* You can delete existing ones via a long press on the item
*/
public class TodoOverviewFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {
private SimpleCursorAdapter adapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
fillData();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.todo_list,
container, false);
return view;
}
// Opens the second activity if an entry is clicked
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Intent i = new Intent(getActivity(), TodoDetailActivity.class);
Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
startActivity(i);
}
private void fillData() {
// Fields from the database (projection)
// Must include the _id column for the adapter to work
String[] from = new String[] { TodoTable.COLUMN_SUMMARY };
// Fields on the UI to which we map
int[] to = new int[] { R.id.label };
getActivity().getSupportLoaderManager().initLoader(0, null, this);
adapter = new SimpleCursorAdapter(getActivity(), R.layout.todo_row, null, from,
to, 0);
setListAdapter(adapter);
}
// Creates a new loader after the initLoader () call
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
String[] projection = { TodoTable.COLUMN_ID, TodoTable.COLUMN_SUMMARY };
CursorLoader cursorLoader = new CursorLoader(getActivity(),
MyTodoContentProvider.CONTENT_URI, projection, null, null, null);
return cursorLoader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// data is not available anymore, delete reference
adapter.swapCursor(null);
}
@Override
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
Intent i = new Intent(getActivity(), TodoDetailActivity.class);
Uri todoUri = Uri.parse(MyTodoContentProvider.CONTENT_URI + "/" + id);
i.putExtra(MyTodoContentProvider.CONTENT_ITEM_TYPE, todoUri);
startActivity(i);
}
}
答案 0 :(得分:1)
致电getActivity().setContentView(R.layout.todo_list);
,您告诉您的活动显示ListView
和空TextView
。您的ListFragment
已包含自动管理的ListView
和空TextView
。所以你正在做的是从你的ListView
布局中单独显示todo_list
,然后修改ListView
中包含的ListFragment
(这就是为什么看起来没有任何内容被加载进入你的ListView
)。如果您只是取消对getActivity().setContentView(R.layout.todo_list);
的通话,只要您正确添加ListFragment
,它就会有效。