I am brand new to Android programming and StackOverFlow. I am working on a journal/tracking app with multiple activities that takes user entries to obtain data and is backed by internal SQLite Database. I am using a custom CursorAdapter so I can make adjustments for images and Loader Manager to manage the database off the UI thread.
The difficulty I am having is getting a GridView to inflate in one fragment of my main activity. The database insertion seems to be working fine, however the GridView is not inflated, I only see a blank screen(the background shows). I have tried changing the fragment containers, and the layout parameters, but these lead to errors and still no GridView. I have tried adjusting the CursorAdaptor parameters - including null, this, or getContext. I have tried attaching the fragment by layout only and attaching programmatically. It is possible there is an error in my fragment attachment because I am still not sure about this. I have included a lot of code because I don't know where the issue is.
I am not getting any errors on the project build currently. Any ideas to what I am doing wrong? Help would be greatly appreciated.
Here is my main Activity which has two fragments MyCritter and KeepMyCritters(GridView). I omitted toolbars and buttons-these work fine.
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);
}
}
Here is my KeepMyCritters Fragment
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);
}
}
Here is my custom 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);
}
}
The database has an _id column and in the debugger it shows the entries are inserted correctly.
The insertCritter code :
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());
}
The content provider:
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);
}
}
Finally here are the layout files:
MyCritter (MainActivity) 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 Fragment 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>
My gridview - item 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>
I believe the issue is I was using a coordinator layout with the GridView. I have now seen prior posts explaining that the coordinator layout and Gridview dont work together. There were several workarounds presented but I could not figure out how to implement these with my particular project. I scrapped the coordinator layout and got the gridview to work properly. I did have an issue with trying to cast a uri to cursor in the cursor adapter which I changed to get it to work. I am still open to other solutions to get these to work together because the coordinator layout is smooth and more precise appearing.