0

いくつかのタブを表示している SherlockFragmentActivity があります。各タブは ListFragment です。

各 ListFragment は次のように作成されます。

ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayOptions(0, ActionBar.DISPLAY_SHOW_TITLE);
bar.setDisplayHomeAsUpEnabled(true);
bar.setDisplayShowTitleEnabled(true);

// users event list
bar.addTab(bar.newTab()
    .setTag("contacts_list")
    .setText(getString(R.string.list_contacts_header))
    .setTabListener(new TabListener<ContactListFragment>(
        this, getString(R.string.list_events_header), ContactListFragment.class, null)));

次に、各 ListFragments が次のようにロードされます。

public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);

    // database cursor containing all venues for this event
    venuesCursor = getDatasource().getAllVenues(((EventActivity) getActivity()).getEventId());

    // hand the cursor to the system to manage
    getActivity().startManagingCursor(venuesCursor);  

    // bind the columns of the cursor to the list
    String[] from = new String[] { VenuesDataSource.KEY_NAME, VenuesDataSource.KEY_DESCRIPTION };
    int[] to = new int[] { R.id.list_item_title, R.id.list_item_subtitle };

    cursorAdapter = new SimpleCursorAdapter(getActivity(), R.layout.list_item, venuesCursor, from, to);

    // retrieve the listview to populate
    ListView lv = (ListView) getActivity().findViewById(android.R.id.list);

    // set the adapter on the listview
    lv.setAdapter(cursorAdapter);

    // click event for each row of the list
    lv.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> arg0, View view,
                int position, long id) {
            Cursor cursor = cursorAdapter.getCursor();
            cursor.moveToPosition(position);
            Toast.makeText(getActivity(), "Tapped row " + position + "!", Toast.LENGTH_SHORT).show();

        }
    });

    // Start out with a progress indicator.
    setListShown(false);

    // prepare the loader -- either re-connect with an existing one, or start a new one.
    // getLoaderManager().initLoader(0, null, this);

    // load the data
    getActivity().getSupportLoaderManager().initLoader(0, null, this);
}

前述したように、このアクティビティには ListFragments の形式で複数のタブがあります。私が抱えている問題は、タブをクリックして選択すると、

E/AndroidRuntime(2519): java.lang.IllegalArgumentException: column 'name' does not exist

これは間違っています。データベースを表示するためにadbを使用しましたが、不満を言っている列は100%そこにあるため、カーソルまたは何かを閉じないことと関係がある必要があり、上記が実際に間違ったものをロードしたときにカーソル。

編集: CursorLoader コードの追加

public static final class VenueCursorLoader extends SimpleCursorLoader {

    Context mContext;

    public VenueCursorLoader(Context context) {
        super(context);

        mContext = context;
    }

    @Override
    public Cursor loadInBackground() {
        Cursor cursor = null;
        VenuesDataSource datasource = new VenuesDataSource(mContext);

        // TODO: provide the event_id to the getAllVenues method
        cursor = datasource.getAllVenues(((EventActivity) mContext).getEventId());

        if (cursor != null) {
            cursor.getCount();
        }

        return cursor;
    }

}

どんな助けでも大歓迎です..

4

1 に答える 1

1

この質問は本質的にここで答えられます

基本的に、理解する必要があることはすべて回答に記載されています。いくつかの修正を行う必要があります。


  • CursorAdapter最初にnullカーソルを渡す必要があります。LoaderManagerにはCursorLoader、最初のクエリを実行するための があります。(上記の私の答えを参照してください)。また、現在使用しているコンストラクターは非推奨であることに注意してください。代わりにこれを使用する必要があります(0フラグとして渡します)。

    cursorAdapter = new SimpleCursorAdapter( getActivity(), R.layout.list_item, null, from, to, 0);


  • 次の行を削除します。

    getActivity().startManagingCursor(venuesCursor);
    

    の要点はLoaderManager、カーソルを管理することです。「管理するシステムにカーソルを渡す」必要はありません...それはまさにLoaderManager. :)


  • #1 と #2 で説明した理由により、このコード行は不要のようです。

    venuesCursor = getDatasource().getAllVenues(
            ((EventActivity) getActivity()).getEventId());
    

  • また、なぜオーバーライドしているのかわかりませんonItemClick。sを使用しているため、代わりListFragmentにオーバーライドしたいと思われますonListItemClick

  • これらの行を含めた理由はわかりませんが、それらも削除したいようです。

    Cursor cursor = cursorAdapter.getCursor();
    cursor.moveToPosition(position);
    

    ほとんどの場合、アダプタのカーソルは操作しないでください。これは、内部システムによって管理され、LoaderManager.

于 2012-06-22T17:30:22.660 に答える