Android 游标加载程序未在片段中显示数据

Android 游标加载程序未在片段中显示数据,android,android-fragments,android-contentprovider,android-cursorloader,Android,Android Fragments,Android Contentprovider,Android Cursorloader,我有一个应用程序可以执行以下操作:带有ListView的活动显示三个项目:开始、中间、高级。根据用户的选择,应用程序应该转到一个带有ListView的片段,其中显示了底层SQLiteDatabase中的所有项目,其中级别=开始、中间或高级。这第二步对我不起作用。我已经通过调试器验证了我的数据库中有数据,所以这不是问题所在。这是我在初始活动中的代码-来自onItemClick方法: final String[] values = new String[] { "Beginn

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

下面是片段的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(称为StitchProvider)的游标加载程序;SQLITE数据库称为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);

}
公共类ListFrag扩展ListFragment实现LoaderManager.LoaderCallbacks{
私有静态最终字符串缝合表\u BASEPATH=“mytitches\u tbl”;
私有静态最终字符串AUTHORITY=“com.MyKnitCards.project.SQLData”;
公共静态最终Uri缝合\u Uri=Uri.parse(“内容:/”+权限+“/”+缝合表\u基本路径);
私有静态最终字符串[]投影=新字符串[]{“\u id”,“stitchname”};
私人简易程序或适应程序;
私有静态最终整数加载器_ID=0;
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
}
已创建ActivityState上的公共无效(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)this);
}
public void onListItemClick(列表视图l、视图v、整数位置、长id){
字符串项=(字符串)getListAdapter().getItem(位置);
DetailFrag frag=(DetailFrag)getFragmentManager().findFragmentById(R.id.frag_stitchdetail);
if(frag!=null&&frag.isInLayout()){
框架设置文本(项目);
}
}
公共加载器onCreateLoader(int-id,Bundle-args){
String selection=“stitchlevel=”+args.getString(“级别”)+“;
返回(装入器)新游标装入器(getActivity(),缝合URI,
投影,选择,空,空);
}
public void onLoadFinished(加载器,光标){
开关(loader.getId()){
案例加载器\u ID:
swapCursor((android.database.Cursor)游标);
打破
}
}
公共void onLoaderReset(加载器){
mAdapter.swapCursor(空);
}
}

onListItemClick方法用于在细节片段中显示数据,但我从来没有做过这么多。从不显示基于意图中的数据从数据库检索的项目列表

我想到了一些可能的问题:

1) onCreateLoader方法中的查询语法正确吗?例如,它应该是“stitchlevel='start'”。我知道args.getString(“Level”)中的数据是有效的,因为我在调试器中已经完成了它,但是这里的语法正确吗?我假设它应该是标准的SQL语法,但是。。。 2) 在片段的onActivityCreated方法中将值赋值给ViewID时,我是否指向了正确的位置? 3) 类似地,在下一行中,SimpleCursorAdapter,android.R.layout.simple\u list\u item\u 1是否正确?或者应该是R.layout.stitchfragment? 4) 我在ContentProvider的查询方法上设置了一个断点,但从未达到该断点。当创建游标加载程序时,我不应该这样做吗?此外,如果我在列表片段的onLoadFinished方法上放置一个断点,则光标为null。我错过了什么 5) 我被告知片段的onActivityCreated方法中的dataColumns应该包含我的表的_id列。这是真的吗?这对我来说似乎很奇怪,因为列表只显示一条信息:缝合名称。但是,无论此处是否包含_id,片段列表都不会显示任何内容 6) 我是否可以像在片段的onActivityCreatedMethod中那样,通过getLoaderManager.initLoader将包info传递给CursorLoader? 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);
Intent myData=getActivity().getIntent();
Bundle info=myData.getExtras();
字符串级别=info.getString(“级别”);
字符串[]值=新字符串[]{level,level};
ArrayAdapter=新的ArrayAdapter(getActivity(),android.R.layout.simple\u list\u item\u 1,值);
setListAdapter(适配器);
所以我知道我可以在片段中显示数据;它似乎无法与游标加载程序和内容提供程序一起工作。我希望这不是信息过载;如果是的话,我很抱歉。如果有人有任何想法,我将不胜感激

1) onCreateLoader方法中的查询语法正确吗?信息技术 例如,应该读“stitchlevel='start'”。我知道数据 在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) 在片段的 在ActivityCreated方法中,我是否指向正确的位置?3) 类似地,在下一行中,SimpleCursorAdapter是 android.R.layout.simple\u list\u item\u 1是否正确?或者也许应该这样做 是R.layout.stitchfragment吗

否。您提供给adap的
int
数组
String selection = "stitchlevel= ?";
String selectionArgs = new String[] {args.getString("Level")};
return new CursorLoader(getActivity(), STITCHES_URI, PROJECTION, selection, selectionArgs, 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);
@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); 
}