0

我编写了以下类来创建带有自定义列表行的列表视图。我为该项目使用Android Support Library v4 ,并使用ActionBarSherlock库为旧设备集成操作栏。

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文件。

片段列表.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是 via setContentView(R.layout.fragment_list);。而且这个 xml 文件不包含任何容器元素,例如<ListView android:id="@android:id/list" />(我在其他设置中看到的)。

此外:

我想知道是否仍然建议在 a 中使用ViewHolder模式,CursorAdapter或者这种行为是否已经内置。我在其他示例中多次看到它,但那些继承自BaseAdapteror SimpleCursorAdapter


得到教训:

当我试图解决这个问题时,我在某个时候对 XML 文件进行了正确的设置。但另一件事阻碍了我让事情顺利进行。这是您需要注意的。
如果你想在你的行布局中显示多个信息fromColumn,在你的CursorLoader. 否则,您将遇到异常:

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"));
4

1 回答 1

2

您的代码在这两种情况下都适用于我(就像我更改行注释时一样)。唯一的事情:我已将公共空构造函数添加到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;
}
于 2012-08-01T20:50:18.620 回答