0

次のことを行うアプリがあります: ListView を使用したアクティビティには、初級、中級、上級の 3 つの項目が表示されます。ユーザーの選択に応じて、アプリは、Level=Beginning または Intermediate または Advanced である基になる SQLiteDatabase からのすべての項目を表示する ListView を使用して Fragment に移動する必要があります。この2番目のステップはうまくいきません。データベースにデータがあることをデバッガーで確認したので、それは問題ではありません。最初のアクティビティのコードは次のとおりです。これは onItemClick メソッドからのものです。

final String[] values = new String[] {
            "Beginning", "Intermediate", "Advanced"
    };
public void onItemClick(AdapterView<?> parent, View view, int position,
                long id) {
            Intent choice = new Intent(getApplicationContext(), com.MyKnitCards.project.StitchList.class);
            Bundle dataBundle = new Bundle();
            String chosenValue = values[position];
            dataBundle.putString("Level",chosenValue);
            choice.putExtras(dataBundle);
            try {
                startActivity(choice);
}
        }

これは Fragment クラスであり、上記のコードで参照されています。

public class StitchList extends FragmentActivity {
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.stitchfragment);
}

}

次に、stitchfragment.xml という Fragment の XML ファイルを示します。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" >
<fragment android:id="@+id/frag_stitchlist"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize"
class="com.MyKnitCards.project.ListFrag" />
<fragment android:id="@+id/frag_stitchdetail"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.MyKnitCards.project.DetailFrag" />
</LinearLayout>

これが ListFrag クラスです。サポート ライブラリと、StitchProvider という ContentProvider を備えた CursorLoader を使用しています。SQLiteDatabase は SQLData と呼ばれます。

public class ListFrag<Cursor> extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {

private static final String STITCHTABLE_BASEPATH = "MyStitches_tbl";
private static final String AUTHORITY = "com.MyKnitCards.project.SQLData";
public static final Uri STITCHES_URI = Uri.parse("content://" + AUTHORITY + "/" + STITCHTABLE_BASEPATH);
private static final String[] PROJECTION = new String[] { "_id", "stitchname" };
private SimpleCursorAdapter mAdapter;
private static final int LOADER_ID = 0;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

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

    Intent myData = getActivity().getIntent();
    Bundle info = myData.getExtras();   

    String[] dataColumns = { "stitchname", "_id" };
    int[] viewIDs = { R.id.frag_stitchlist };
    mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1, null, dataColumns, viewIDs, 0);
    setListAdapter(mAdapter);
    getLoaderManager().initLoader(0, info, (LoaderCallbacks<Cursor>) this); 

}

public void onListItemClick(ListView l, View v, int position, long id) {
    String item = (String) getListAdapter().getItem(position);
    DetailFrag frag = (DetailFrag) getFragmentManager().findFragmentById(R.id.frag_stitchdetail);
    if (frag != null && frag.isInLayout()) {
        frag.setText(item);
    }
}

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String selection = "stitchlevel='" + args.getString("Level") + "'";
    return (Loader<Cursor>) new CursorLoader(getActivity(), STITCHES_URI,
            PROJECTION, selection, null, null); 
}

public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
      case LOADER_ID:
        mAdapter.swapCursor((android.database.Cursor) cursor);
        break;
    }

}
public void onLoaderReset(Loader<Cursor> loader) {
    mAdapter.swapCursor(null);

}

}

onListItemClick メソッドは、詳細フラグメントにデータを表示するためのものですが、ここまで到達することはありません。Intent のデータに基づいてデータベースから取得されたアイテムのリストは表示されません。

いくつかの考えられる問題/質問が思い浮かびます:

1) onCreateLoader メソッドのクエリの構文は正しいですか? たとえば、「stitchlevel='Beginning'」と読みます。args.getString("Level") のデータが有効であることはわかっています。これは、デバッガーで追跡したためですが、ここでの構文は正しいですか? 私はそれが標準的な SQL 構文であるべきだと仮定していますが... 3) 同様に、次の行の SimpleCursorAdapter は、ここで android.R.layout.simple_list_item_1 は正しいですか? それとも、おそらく R.layout.stitchfragment である必要がありますか? 4) ContentProvider のクエリ メソッドにブレークポイントを設定しましたが、ブレークポイントにヒットしませんでした。CursorLoader が作成されたときにすべきではないですか? さらにList FragmentのonLoadFinishedメソッドにブレークポイントを入れると、カーソルはヌルです。何が欠けていますか 5) Fragment の onActivityCreated メソッドの dataColumns には、テーブルの _id 列を含める必要があると言われました。本当?リストにはステッチ名という 1 つの情報しか表示されないので、私には奇妙に思えます。ただし、_id がここに含まれているかどうかに関係なく、フラグメント リストには何も表示されません。7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです.... 何が欠けていますか 5) Fragment の onActivityCreated メソッドの dataColumns には、テーブルの _id 列を含める必要があると言われました。本当?リストにはステッチ名という 1 つの情報しか表示されないので、私には奇妙に思えます。ただし、_id がここに含まれているかどうかに関係なく、フラグメント リストには何も表示されません。7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです.... 欠けているもの 5) Fragment の onActivityCreated メソッドの dataColumns には、テーブルの _id 列を含める必要があると言われました。本当?リストにはステッチ名という 1 つの情報しか表示されないので、私には奇妙に思えます。ただし、_id がここに含まれているかどうかに関係なく、フラグメント リストには何も表示されません。7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです.... リストにはステッチ名という 1 つの情報しか表示されないためです。ただし、_id がここに含まれているかどうかに関係なく、フラグメント リストには何も表示されません。7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです.... リストにはステッチ名という 1 つの情報しか表示されないためです。ただし、_id がここに含まれているかどうかに関係なく、フラグメント リストには何も表示されません。7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです.... フラグメントの onActivityCreatedMethod で行うように? 7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです.... フラグメントの onActivityCreatedMethod で行うように? 7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?どちらも私を助けないようです....

単純にこれを行うと、フラグメントを表示することができました:

Intent myData = getActivity().getIntent();
    Bundle info = myData.getExtras();
    String level = info.getString("Level");
    String[] values = new String[] {level, level};
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, values);
    setListAdapter(adapter);

したがって、フラグメントにデータを表示できることはわかっています。CursorLoader と ContentProvider で動作していないようです。これが情報の過負荷でないことを願っています。もしそうなら申し訳ありません。誰かに何かアイデアがあれば、私はとても感謝しています。

4

1 に答える 1

1

1) onCreateLoader メソッドのクエリの構文は正しいですか? たとえば、「stitchlevel='Beginning'」と読みます。args.getString("Level") のデータが有効であることはわかっています。これは、デバッガーで追跡したためですが、ここでの構文は正しいですか? 私はそれが標準のSQL構文であるべきだと仮定していますが、

はい、正しいです。さらに良いのは次のとおりです。

String selection = "stitchlevel= ?";
String selectionArgs = new String[] {args.getString("Level")};
return new CursorLoader(getActivity(), STITCHES_URI, PROJECTION, selection, selectionArgs, null); 

2) Fragment の onActivityCreated メソッドでの viewID への値の割り当てで、正しい場所を指していますか? 3) 同様に、次の行の SimpleCursorAdapter は、ここで android.R.layout.simple_list_item_1 は正しいですか? それとも、おそらく R.layout.stitchfragment である必要がありますか?

いいえ。intアダプターに提供する配列は、アダプターで使用される行レイアウトの ID を表し、作成したようなフラグメントの ID ではありません。android.R.layout.simple_list_item_1( a のみで構成される)を使用する場合は、そのTextViewを提供する必要があります。これは次のとおりです。idTextViewandroid.R.id.text1

String[] dataColumns = { "stitchname"};
int[] viewIDs = { android.R.id.text1 };
mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1, null, dataColumns, viewIDs, 0);

4) ContentProvider のクエリ メソッドにブレークポイントを設定しましたが、ブレークポイントにヒットしませんでした。CursorLoader が作成されたときにすべきではないですか? さらに、List Fragment の onLoadFinished メソッドにブレークポイントを設定すると、カーソルが null になります。何が足りないの

前回の質問で私が推奨したことをしなかったと思います。プロバイダーのqueryメソッドは少なくとも呼び出されている必要があり、これが起こらない場合は 1 つのオプションが残ります。をキャストしたのに、 からのコールバック メソッドLoadersの注釈が欠落していることに気付きました。これらのメソッドに注釈を追加します。OverrideLoaderManager.LoaderCalbbacksOverride

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String selection = "stitchlevel= ?";
    String selectionArgs = new String[] {args.getString("Level")};
    return new CursorLoader(getActivity(), STITCHES_URI,
            PROJECTION, selection, selectionArgs, null); 
}

そして何が起こるか見てください。エラーが発生した場合は、正しいインポートを使用していることを確認し、互換パッケージのクラスまたは通常のクラスのみを使用してください (ファイルからすべてのインポートを簡単に削除してから、すべてを再インポートしてクラスを使用できますandroid.support.v4)。勝手な推測です。

5) Fragment の onActivityCreated メソッドの dataColumns には、テーブルの _id 列を含める必要があると言われました。本当?リストにはステッチ名という 1 つの情報しか表示されないので、私には奇妙に思えます。ただし、ここに _id が含まれているかどうかに関係なく、Fragment リストには何も表示されません。

Cursorベースのアダプタでは、使用されるCursorに という名前の列が含まれている必要があります_id(のスーパークラスであるクラスのドキュメントを参照してくださいCursorAdapterSimpleCursorAdapter)。Stringアダプターに設定されている配列に存在する必要はありません。

6) Fragment の onActivityCreatedMethod で行っているように、getLoaderManager.initLoader を介してバンドル情報を CursorLoader に渡すのは適切ですか?

はい。ただし、ID に関しては、一貫性を保つ必要があります。使用LOADER_IDする場合は、コード内の特定の場所だけでなく、どこでも使用してください。または、1 つLoaderだけを使用する場合は、どこでも使用できます (そのため、メソッドで0をテストする必要はありません)。LOADER_IDonLoadFinished

7) Fragment の onActivityCreated メソッドで getLoaderManager().initLoader() の前に setListAdapter が呼び出される例と、setListAdapter が後で呼び出される例を見てきました。どちらが正しい?

どちらも使用できます。アダプターを設定してから初期化しLoaderます。

于 2012-11-13T22:09:01.777 に答える