0

我有一个应用程序,它执行以下操作:带有 ListView 的 Activity 显示三个项目:Beginning、Intermediate、Advanced。根据用户的选择,应用程序应该转到带有 ListView 的 Fragment,它显示来自底层 SQLiteDatabase 的所有项目,其中 Level=Beginning 或 Intermediate 或 Advanced。这第二步对我不起作用。我已经通过调试器验证了我的数据库中有数据,所以这不是问题。这是我在初始 Activity 中的代码 - 这是来自 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);
}
        }

这是 StitchList 类,它是 Fragment 类,在上面的代码中引用:

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

}

这是 Fragment 的 XML 文件,称为stitchfragment.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 类。我正在使用支持库和带有 ContentProvider 的 CursorLoader,称为 StitchProvider;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 语法,但是...... 2)在片段的 onActivityCreated 方法中为 viewID 分配值时,我是否指向正确的位置?3) 同样,在下一行 SimpleCursorAdapter 中,这里的 android.R.layout.simple_list_item_1 是否正确?还是应该是 R.layout.stitchfragment?4)我在ContentProvider的查询方法上放了一个断点,我从来没有打过断点。创建 CursorLoader 时不应该吗?此外,如果我在 List Fragment 的 onLoadFinished 方法上设置断点,光标为空。我错过了什么 5) 我被告知 Fragment 的 onActivityCreated 方法中的 dataColumns 应该包含我的表的 _id 列。真的吗?这对我来说似乎很奇怪,因为列表只会显示一条信息:stitchname。但是,无论此处是否包含 _id,Fragment 列表都不会显示任何内容 6) 我是否可以像在 Fragment 的 onActivityCreatedMethod 中那样通过 getLoaderManager.initLoader 将 Bundle、信息传递给 CursorLoader?7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?似乎都没有帮助我.... 我错过了什么 5) 我被告知 Fragment 的 onActivityCreated 方法中的 dataColumns 应该包含我的表的 _id 列。真的吗?这对我来说似乎很奇怪,因为列表只会显示一条信息:stitchname。但是,无论是否包含 _id,Fragment 列表都不会显示任何内容 6) 我是否可以像在 Fragment 的 onActivityCreatedMethod 中那样通过 getLoaderManager.initLoader 将 Bundle、信息传递给 CursorLoader?7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?似乎都没有帮助我.... 我错过了什么 5) 我被告知 Fragment 的 onActivityCreated 方法中的 dataColumns 应该包含我的表的 _id 列。真的吗?这对我来说似乎很奇怪,因为列表只会显示一条信息:stitchname。但是,无论是否包含 _id,Fragment 列表都不会显示任何内容 6) 我是否可以像在 Fragment 的 onActivityCreatedMethod 中那样通过 getLoaderManager.initLoader 将 Bundle、信息传递给 CursorLoader?7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?似乎都没有帮助我.... 因为该列表只会显示一条信息:针迹名称。但是,无论此处是否包含 _id,Fragment 列表都不会显示任何内容 6) 我是否可以像在 Fragment 的 onActivityCreatedMethod 中那样通过 getLoaderManager.initLoader 将 Bundle、信息传递给 CursorLoader?7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?似乎都没有帮助我.... 因为该列表只会显示一条信息:针迹名称。但是,无论此处是否包含 _id,Fragment 列表都不会显示任何内容 6) 我是否可以像在 Fragment 的 onActivityCreatedMethod 中那样通过 getLoaderManager.initLoader 将 Bundle、信息传递给 CursorLoader?7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?似乎都没有帮助我.... 就像我在 Fragment 的 onActivityCreatedMethod 中所做的那样?7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?似乎都没有帮助我.... 就像我在 Fragment 的 onActivityCreatedMethod 中所做的那样?7) 我已经看到在片段的 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);

所以我知道我可以在 Fragment 中显示数据;它似乎不适用于 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),则必须提供idthat TextView,即android.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 方法上放置一个断点,则光标为空。我错过了什么

我认为你没有按照我在上一个问题上建议的那样做。query至少应该调用提供者的方法,而这没有发生,只剩下一个选择。我注意到您投射了Loaders并且您缺少Override来自LoaderManager.LoaderCalbbacks. 将Override注释添加到这些方法:

@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 列。真的吗?这对我来说似乎很奇怪,因为列表只会显示一条信息:stitchname。但是,无论这里是否包含 _id,Fragment 列表都不会显示任何内容

Cursor基于的适配器要求 usedCursor必须包含一个名为的列_id请参阅该类的文档,CursorAdapter该类的超类SimpleCursorAdapter)。它不需要出现在String设置到适配器中的数组中。

6) 我是否可以像在 Fragment 的 onActivityCreatedMethod 中那样通过 getLoaderManager.initLoader 将 Bundle、信息传递给 CursorLoader?

是的。但是关于 id,请保持一致,如果您要在LOADER_ID任何地方使用它,而不仅仅是在代码中的某些地方使用它。或者更好的是,如果您Loader只使用一个,就0在任何地方使用(因此无需测试方法中的LOADER_IDin onLoadFinished)。

7) 我已经看到在片段的 onActivityCreated 方法中在 getLoaderManager().initLoader() 之前调用 setListAdapter 的示例,并且我看到了之后调用 setListAdapter 的示例。哪个是对的?

两者都可以使用。我会设置适配器,然后初始化Loader.

于 2012-11-13T22:09:01.777 回答