我有一个应用程序执行以下操作:带有ListView的Activity显示三个项目:Beginning,Intermediate,Advanced。根据用户的选择,应用程序应转到带有ListView的片段,该列表显示基础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)在Fragment的onActivityCreated方法中为viewID分配值时,我指的是正确的位置吗? 3)同样,在下一行,SimpleCursorAdapter,android.R.layout.simple_list_item_1在这里是否正确?或者它应该是R.layout.stitchfragment? 4)我在ContentProvider的查询方法上放了一个断点,我从未点过断点。创建CursorLoader时不应该吗?此外,如果我在List Fragment的onLoadFinished方法上放置一个断点,则游标为null。我错过了什么 5)我被告知片段的onActivityCreated方法中的dataColumns应该包含我的表的_id列。真的吗?这对我来说似乎很奇怪,因为列表只显示一条信息:stitchname。但是,无论是否包含_id,片段列表都不会显示任何内容 6)我是否应该通过getLoaderManager.initLoader将Bundle,info传递给CursorLoader,就像在Fragment的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。我希望这不是信息过载;道歉,如果是的话。如果有人有任何想法,我将非常感激。
答案 0 :(得分: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)在片段中为viewID分配值 onActivityCreated方法,我指的是正确的地方吗? 3) 同样,在下一行中,SimpleCursorAdapter是 android.R.layout.simple_list_item_1在这里更正?或者也许应该 是R.layout.stitchfragment?
没有。您提供给适配器的int
数组表示适配器中使用的行布局中的ID,而不是您编写的片段的ID。如果您使用android.R.layout.simple_list_item_1
(仅包含TextView
),则必须提供id
的{{1}},即TextView
:
android.R.id.text1
4)我在ContentProvider的查询方法上放了一个断点,我从来没有 打破了断点。创建CursorLoader时不应该吗? 此外,如果我在List Fragment上放置一个断点 onLoadFinished方法,游标为null。我缺少什么
我认为你在上一个问题上没有做我推荐你的事。应该至少调用提供者的String[] dataColumns = { "stitchname"};
int[] viewIDs = { android.R.id.text1 };
mAdapter = new SimpleCursorAdapter(getActivity(), android.R.layout.simple_list_item_1, null, dataColumns, viewIDs, 0);
方法,并且这种情况不会发生,只留下一个选项。我注意到你施放了query
而你错过了来自Loaders
的回调方法的Override
注释。将LoaderManager.LoaderCalbbacks
注释添加到这些方法中:
Override
看看会发生什么。如果出现错误,请确保使用了正确的导入,并且只使用兼容包中的类或普通的类(您可以轻松地从文件中删除所有导入,然后重新导入所有内容并使用{{1}的类})。只是一个疯狂的猜测。
基于5)我被告知Fragment的onActivityCreated中的dataColumns 方法应该包含我的表的_id列。真的吗?它似乎 对我来说很奇怪,因为列表只显示一条信息: stitchname。但是,无论是否包含_id,都是 片段列表不显示任何内容
@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
必须包含名为Cursor
(see the documentation of the CursorAdapter
class的列,Cursor
的超类。它不需要出现在设置到适配器中的_id
数组中。
6)将Bundle,info传递给CursorLoader是否合适 通过getLoaderManager.initLoader,就像我在Fragment中所做的那样 onActivityCreatedMethod?
是。但是关于id,要保持一致,如果你打算使用SimpleCursorAdapter
在任何地方使用它,而不仅仅是在你的代码中的某些地方。或者甚至更好,如果您只使用一个String
,只需在任何地方使用LOADER_ID
(因此无需在Loader
方法中测试0
7)我见过之前调用过setListAdapter的例子 片段的onActivityCreated中的getLoaderManager()。initLoader() 方法和我见过的例子,其中调用了setListAdapter。 哪个是对的?
两者都可以使用。我会设置适配器,然后初始化LOADER_ID
。