如何在使用自定义 CursorAdapter 和 Cursor Loader 时让 GridView 和 GridView 项目在片段中膨胀?

How to get GridView and GridView Item to Inflate in a Fragment while using Custom CursorAdapter and Cursor Loader?

我是 Android 编程和 Whosebug 的新手。我正在开发一个包含多个活动的 journal/tracking 应用程序,该应用程序需要用户输入以获取数据并由内部 SQLite 数据库支持。我正在使用自定义 CursorAdapter,因此我可以对图像和加载程序管理器进行调整,以在 UI 线程之外管理数据库。

我遇到的困难是让 GridView 在我的主要 activity 的一个片段中膨胀。数据库插入似乎工作正常,但是 GridView 没有膨胀,我只看到一个空白屏幕(背景显示)。我已经尝试更改片段容器和布局参数,但这些会导致错误并且仍然没有 GridView。我已尝试调整 CursorAdaptor 参数 - 包括 null、this 或 getContext。我试过仅按布局附加片段并以编程方式附加。我的片段附件中可能有错误,因为我仍然不确定这一点。我已经包含了很多代码,因为我不知道问题出在哪里。

我目前在项目构建中没有收到任何错误。对我做错了什么有什么想法吗?将不胜感激。

这是我的主要 Activity,它有两个片段 MyCritter 和 KeepMyCritters(GridView)。我省略了工具栏和按钮 - 这些工作正常。

public class MyCritter extends Critters implements        KeepMyCritters.OnFragmentInteractionListener,LoaderManager.LoaderCallbacks<Cursor> {

private KeepMyCritters critterFragment;
private Intent intent;

public CursorAdapter cursorAdapter;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_my_critters);


    cursorAdapter = new CritterCursorAdapter(this, null, 0);

    getSupportLoaderManager().initLoader(0,null,this);

    InsertNewCritter(_id, "Sherman");
    InsertNewCritter(_id,"Charlie");

  critterFragment = new KeepMyCritters();
   setFragment(critterFragment);

}

public void setFragment(Fragment frag){
    FragmentManager fm = getSupportFragmentManager();
    fm.findFragmentById(R.id.container);
    if (frag == null) {fm.beginTransaction().add(R.id.container, critterFragment).commit();

}

@Override
public void onFragmentInteraction(long _id) {
    Toast.makeText(getApplicationContext(),"You selected a Critter to View", Toast.LENGTH_LONG).show();
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
 CursorLoader cursorLoader = new CursorLoader(this, CritterProvider.CONTENT_URI, null, null, null, null);
    return cursorLoader;
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    cursorAdapter.swapCursor(data);
}

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

}

这是我的 KeepMyCritters 片段

public class KeepMyCritters extends Fragment implements LoaderManager.LoaderCallbacks<Cursor>,AdapterView.OnItemClickListener{


CritterCursorAdapter cursorAdapter;

private OnFragmentInteractionListener mListener;

public KeepMyCritters() {
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_keep_my_critters, container, false);

    cursorAdapter = new CritterCursorAdapter(getContext(), (Cursor)CritterProvider.CONTENT_URI,0);

    GridView gv =(GridView) view.findViewById(R.id.gridview);


    gv.setAdapter(cursorAdapter);
    gv.setOnItemClickListener(this);

    getLoaderManager().initLoader(0,null,this);
    return view;

}


@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        mListener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString()
                + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach(){
    super.onDetach();
    mListener=null;

}

@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
    Uri CritterUri = ContentUris.withAppendedId(CritterProvider.CONTENT_URI, l );
    if(mListener !=null) {
        mListener.onFragmentInteraction(l);
    }
}

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    return new CursorLoader(getContext(), CritterProvider.CONTENT_URI, null, null, null, null);
}

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    cursorAdapter.swapCursor(cursor);

}

@Override
public void onLoaderReset(Loader<Cursor> loader) {
    cursorAdapter.swapCursor(null);

}


public interface OnFragmentInteractionListener {

    void onFragmentInteraction(long id);
}

}

这是我自定义的 CursorAdapter class

public class CritterCursorAdapter extends CursorAdapter {
public CritterCursorAdapter(Context context, Cursor cursor, int flags) {
    super(context, cursor, flags);
}

Context c;
private LayoutInflater inflater;
 private GridView gv;


@Override
public View newView(Context context, Cursor cursor, ViewGroup viewGroup) {
    return inflater.inflate(R.layout.fragment_item_grid, gv);
}

@Override
public void bindView(View view, Context context, Cursor cursor) {

    String name = cursor.getString(
            cursor.getColumnIndex(CritterDatabaseHelper.NAME));

    TextView hName = (TextView) view.findViewById(R.id.critterName);
    hName.setText(name);

}

}

数据库有一个 _id 列,在调试器中它显示条目已正确插入。

insertCritter代码:

protected void InsertNewCritter(int _id, String name) {
    ContentValues values = new ContentValues();
    values.put(CrittersDatabaseHelper.NAME, name);

    Uri crittersUri = getContentResolver().insert(CritterProvider.CONTENT_URI, values);
    Log.d("MyCritter", "Inserted data " + crittersUri.getLastPathSegment());
}

内容提供者:

public class CritterProvider extends ContentProvider {

private static final String AUTHORITY = mypackage.critterProvider";
private static final String BASE_PATH = "critters";

public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);

private static final int CRITTERS = 1;
private static final int CRITTERS_ID = 2;

private static final UriMatcher uriMatcher =
        new UriMatcher(UriMatcher.NO_MATCH);

static {
    uriMatcher.addURI(AUTHORITY, BASE_PATH, CRITTERS);
    uriMatcher.addURI(AUTHORITY, BASE_PATH + " /# ", CRITTERS_ID);
}


private SQLiteDatabase db;

@Override
public boolean onCreate() {
    CrittersDatabaseHelper cdb = new CrittersDatabaseHelper(getContext());
    db = cdb.getWritableDatabase();
    return true;
}


@Nullable
@Override
public Cursor query(Uri uri, String[] strings, String selection, String[] selectionArgs, String sortOrder) {
    return db.query(CrittersDatabaseHelper.TABLE_MAIN, CrittersDatabaseHelper.ALL_TABLE_MAIN_COLUMNS, selection, selectionArgs, null, null, null);
}

@Override
public String getType(Uri uri) {
    return null;
}

@Nullable
@Override
public Uri insert(Uri uri, ContentValues values) {
    long id = db.insert(CrittersDatabaseHelper.TABLE_MAIN, null, values);
    return Uri.parse(BASE_PATH + "/" + id);

}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    return db.delete(CrittersDatabaseHelper.TABLE_MAIN, selection, selectionArgs);
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    return db.update(CrittersDatabaseHelper.TABLE_MAIN, values, selection, selectionArgs);
}

}

最后是布局文件:

MyCritter(主要Activity)xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout     xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="@color/colorPrimaryDark"
tools:context="com.mypackage.Activities.MyCritters">


<HorizontalScrollView
    android:layout_width="wrap_content"
    android:layout_height="match_parent">



    <LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:orientation="horizontal">

        <include layout="@layout/content_my_critter"
         android:layout_height="match_parent"
         android:layout_width="422dp" />

        <include layout="@layout/fragment_keep_my_critters"
            android:layout_height="match_parent"
            android:layout_width="422dp"/>

    </LinearLayout>

</HorizontalScrollView>

KeepMyCritters 片段xml:

<FrameLayout  xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/jungle"
tools:context="com.mypackage.Fragments.KeepMyCritters"
tools:showIn="@layout/activity_my_critter">


<TextView
    android:text="My Critters"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/textView"
    android:textAppearance="@style/TextAppearance.AppCompat.Display1"
    android:gravity="center"
    android:textColor="@color/colorAccent" />

<GridView
    android:id="@+id/gridview"
    android:layout_width="match_parent"
    android:layout_height="546dp"
    android:columnWidth="120dp"
    android:numColumns="auto_fit"
    android:verticalSpacing="30dp"
    android:stretchMode="columnWidth"
    android:gravity="center"
    android:layout_alignParentBottom="true" />


</FrameLayout>

我的 gridview - 项目 xml:

?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/fragment_item_grid"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
tools:showIn="@layout/fragment_keep_my_critters">


<TextView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:id="@+id/critterName"
    android:layout_weight="1"
    android:textAppearance="@style/TextAppearance.AppCompat.Display1"
    android:gravity="center"
    android:textColor="#3bae1b"
    android:textStyle="normal|bold|italic" />


</LinearLayout>

我认为问题是我在 GridView 中使用了协调器布局。我现在看到以前的帖子解释协调器布局和 Gridview 不能一起工作。提出了几种解决方法,但我无法弄清楚如何在我的特定项目中实施这些方法。我取消了协调器布局并让 gridview 正常工作。我在尝试将 uri 投射到游标适配器中的游标时确实遇到了问题,我更改了游标适配器以使其正常工作。我仍然对其他解决方案持开放态度,因为协调器布局流畅且更精确。