ListFragment:CursorAdapter中的findViewById返回null
我写了下列类来创建一个具有自定义列表行的列表视图。我使用Android支持库v4作为项目和ActionBarSherlock库来集成旧设备的操作栏。ListFragment:CursorAdapter中的findViewById返回null
public class CustomListActivity extends SherlockFragmentActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
setTheme(R.style.Sherlock___Theme_DarkActionBar);
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_list);
}
}
...
public class ListFragment extends SherlockListFragment implements LoaderCallbacks<Cursor> {
private Activity mActivity;
private CursorAdapter mAdapter;
// Query parameter as members ...
private String mFromColumns;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setEmptyText("No data to display");
mActivity = getActivity();
// Query parameters are stored in members here ...
mFromColumns = { "_id", "name" };
mAdapter = new CustomCursorAdapter(mActivity, null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle extras) {
return new CursorLoader(mActivity, mUri, mFromColumns, mSelection, mSelectionArgs, sortOrder);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mAdapter.swapCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
...
public class CustomCursorAdapter extends CursorAdapter {
private LayoutInflater mInflater;
public CustomCursorAdapter(Context context, Cursor cursor, int flags) {
super(context, cursor, flags);
mInflater = LayoutInflater.from(context);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView listItem = (TextView)view.findViewById(R.id.name);
// TextView listItem = (TextView)view.findViewById(android.R.id.text1);
String text = cursor.getString(cursor.getColumnIndex("name"));
listItem.setText(text);
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return mInflater.inflate(R.layout.list_item, parent, false);
// return mInflater.inflate(android.R.layout.simple_list_item_1, parent, false);
}
}
列表视图成功地加载和显示数据行,当我使用了框架提供的列表项和布局(未注释行CustomCursorAdapter
)。但是,当我交换行来使用我的自定义布局和列表项时,findViewById
返回null
。这里是xml文件。
fragment_list.xml
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.example.app.fragment.ListFragment"
android:id="@+id/list_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</fragment>
list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<TextView
android:id="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</TextView>
</LinearLayout>
我敢肯定,问题是我如何连接的XML文件或他们是如何构建。我希望你能看到错误。实际上,我不明白如何使用list_item.xml
作为列表视图的行布局。我设置为fragment_list.xml
的唯一参考是通过setContentView(R.layout.fragment_list);
。而这个XML文件不包含任何容器元素,如<ListView android:id="@android:id/list" />
(我在其他设置中看到)。
此外:
我想知道,如果它仍然建议使用ViewHolder模式在CursorAdapter
如果此行为是内置了。我在其他例子中多次看到它,但是从BaseAdapter
或SimpleCursorAdapter
继承的那些。
教训:
当我试图解决这个问题,我有权利设置somewhen的XML文件。但另一件事阻碍了我让事情继续下去。这是你需要注意的。
如果要在行布局中显示多个信息,请在CursorLoader
的fromColumn
参数中包含关联的列名称,这一点很重要。否则,你会遇到一个例外:
java.lang.IllegalStateException: get field slot from row 0 col -1 failed
在fromColumns
每列名...
String[] fromColumns = { "_id", "name", "comments" }
...是关系到你的要求光标。 _id
列必须使用游标作为迭代器。
String name = cursor.getString(cursor.getColumnIndex("name"));
String comment = cursor.getString(cursor.getColumnIndex("comment"));
您的代码在两种情况下都适用于我(因为和当我更改行注释时)。唯一的事情是:我已将公共空构造函数添加到ListFragment
。
而且还建议使用ViewHolder
模式与CursorAdapter
。
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
if (holder == null) {
holder = new ViewHolder();
holder.name = (TextView) view.findViewById(R.id.name);
view.setTag(holder);
}
String text = cursor.getString(cursor.getColumnIndex("name"));
holder.name.setText(text);
}
private static class ViewHolder {
TextView name;
}
有相同的空问题。我只是意识到,构造函数中的行布局在newView方法中不一样。所以我在定位id的时候,在膨胀视图时不在行布局中。 – 2014-12-01 20:35:27