0

カスタムリスト行を含むリストビューを作成するために、次のクラスを作成しました。プロジェクトにはAndroidSupportLibrary 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ファイルです。

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);です。<ListView android:id="@android:id/list" />また、このxmlファイルには、 (他のセットアップで見た)などのコンテナー要素は含まれていません。

さらに:

でViewHolderパターンを使用することがまだ推奨されているのか、CursorAdapterそれともこの動作がすでに組み込まれているのかを知りたいのですが。他の例でも何度か見ましたが、BaseAdapterまたはから継承したものSimpleCursorAdapterです。


学んだ教訓:

問題を解決しようとしていたとき、いつかXMLファイルの正しい設定ができました。しかし、別のことが私が物事を実行するのを妨げました。これがあなたが知っておくべきことです。行レイアウトに複数の情報
を表示する場合は、のパラメーターに関連する列名を含めることが重要です。そうしないと、例外が発生します。fromColumnCursorLoader

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

あなたのコードは私にとって両方の場合で機能します(私が行コメントを変更したときと同じように)。唯一のこと:publicemptyコンストラクターをに追加しました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 に答える