Search code examples
androidandroid-listviewsimplecursoradapter

ListView content not shown using SimpleCursorAdapter unless i click/tap on list item


I am facing a strange problem while populating a ListView using SimpleCursorAdapter, My source code for ListFragment is given below.

*THE PROBLEM: * after adding some data in the list via my addEditTaskActivity (i have tested that there is nothing wrong with insertion.) the content of the ListView is not show. But when i click/tap on the List Item the correct data is shown.

I don't know what i am doing wrong here.

TasksListFragment.java

public class CourseTaskListFragment extends SherlockListFragment implements
        LoaderCallbacks<Cursor>, OnItemClickListener {

private LoaderManager mLoaderManager;
private ListView mListView;
protected int dialogOkCancel;
protected long selectedTID;
private CursorLoader mCursorLoader;
private AsyncQueryHandler mAsyncQueryHandler;
private Cursor mCursor;
private Context context;
private long semesterID_FK;
private SimpleCursorAdapter mSimpleTaskListAdapter;

// ---------------------------------------------------------------------

public CourseTaskListFragment(Context context, long currentCourseId,
        long semesterID_FK) {
    super();
    this.currentCourseId = currentCourseId;
    this.semesterID_FK = semesterID_FK;
    this.context = context;
}

// ---------------------------------------------------------------------

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(StudyManagerDataSource.LOG_TAG,
            "TaskListFragment onCreate called!");
    // Enable the option menu for the Fragment
    setHasOptionsMenu(true);

    setRetainInstance(true);


    mSimpleTaskListAdapter = new SimpleCursorAdapter(context,
            android.R.layout.simple_list_item_1, null,
            new String[] { Task.COL_NAME },
            new int[] { android.R.id.text1 },
            SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    setListAdapter(mSimpleTaskListAdapter);

    mLoaderManager = getLoaderManager();
    mLoaderManager.initLoader(1, null, this);

} // end onCreate

// ---------------------------------------------------------------------
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    return inflater
            .inflate(R.layout.course_task_fragment, container, false);
}

// ---------------------------------------------------------------------

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mListView = getListView();
    mListView.setLongClickable(true);

    registerForContextMenu(mListView);

    mListView.setOnItemClickListener(this);
    mListView.setOnItemLongClickListener(this);
}

// -----------------------------------------------------------------

@Override
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {

    mCursorLoader = new CursorLoader(getActivity(), Task.CONTENT_URI,
            Task.allColumns, Task.COL_COURSE_ID_FK + " = ? and "
                    + Task.COL_SEMESTER_ID_FK + " = ? ", new String[] {
                    String.valueOf(currentCourseId),
                    String.valueOf(semesterID_FK) }, null);

    return mCursorLoader;
}

// -----------------------------------------------------------------

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
    // TODO Auto-generated method stub
    if (mSimpleTaskListAdapter != null && cursor.moveToFirst()) {
        mSimpleTaskListAdapter.swapCursor(cursor);

    } else {

    }

}

// -----------------------------------------------------------------
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
    if (mSimpleTaskListAdapter != null)
        mSimpleTaskListAdapter.swapCursor(null);

    }


}

and the source code of my layout is:

*course_task_fragment.xml*

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center_horizontal|center_vertical"
    android:orientation="vertical" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>

    <TextView
        android:id="@android:id/empty"
        style="@style/emptyListMessage"
        android:text="@string/no_homework" />

</RelativeLayout>

Solution

  • A Fragment already has a reference to a Context(the Activity where is used) which can be retrieved with a call to getActivity(). You should use that method to initialize your adapter instance.

    Related to your implementation:

    You should avoid implementing an arguments constructor like you did. The reason for this is that the Android system might try to recreate your fragment at a later point(in a ViewPager, after a configuration change etc) and it will do that by calling the no arguments constructor(which is not implemented in your case). You'll also lose the data values that you passed in.

    You don't need to pass the Context, the rest you can pass in a Bundle as arguments:

    Bundle args = new Bundle();
    args.put("course_id", long currentCourseId);
    args.put("semester", long semesterID_FK);
    // pass this to the fragment instance instead of the constructor
    CourseTaskListFragment fragment = new CourseTaskListFragment(); // your current constructor would be removed
    fragment.setArguments(args);
    

    In the fragment you could then use:

    getArguments().getLong("couser_id");
    getArguments().getLong("semester");
    

    to get the values.