Content loaders

Content loaders provide you with a mechanism to load data from a content provider or other data source for display in a UI component, such as Activity or Fragment. These are the benefits that loaders provide:

We will create our content loader implementation. First, we need to update the Adapter class. Since we will deal with cursors, we will use a CursorAdapter instead of BaseAdapter. CursorAdapter accepts a Cursor instance as a parameter in the primary constructor. The CursorAdapter implementation is much simpler than the one we have right now. Open EntryAdapter and update it as follows:

    class EntryAdapter(ctx: Context, crsr: Cursor) : CursorAdapter(ctx,
crsr) { override fun newView(p0: Context?, p1: Cursor?, p2: ViewGroup?):
View { val inflater = LayoutInflater.from(p0) return inflater.inflate(R.layout.adapter_entry, null) } override fun bindView(p0: View?, p1: Context?, p2: Cursor?) { p0?.let { val label = p0.findViewById<TextView>(R.id.title) label.text = cursor.getString( cursor.getColumnIndexOrThrow(DbHelper.COLUMN_TITLE) ) } } }

We have the following two methods to override:

Finally, let's update our ItemsFragment class, so it uses the content loader implementation:

    class ItemsFragment : BaseFragment() { 
      ... 
      private var adapter: EntryAdapter? = null 
      ... 
      private val loaderCallback = object :
LoaderManager.LoaderCallbacks<Cursor> { override fun onLoadFinished(loader: Loader<Cursor>?, cursor:
Cursor?) { cursor?.let { if (adapter == null) { adapter = EntryAdapter(activity, cursor) items.adapter = adapter } else { adapter?.swapCursor(cursor) } } } override fun onLoaderReset(loader: Loader<Cursor>?) { adapter?.swapCursor(null) } override fun onCreateLoader(id: Int, args: Bundle?):
Loader<Cursor> { return CursorLoader( activity, Uri.parse(JournalerProvider.URL_NOTES), null, null, null, null ) } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) loaderManager.initLoader( 0, null, loaderCallback ) } override fun onResume() { super.onResume() loaderManager.restartLoader(0, null, loaderCallback) val btn = view?.findViewById
<FloatingActionButton>(R.id.new_item) btn?.let { animate(btn, false) } } }

We initialize LoaderManager by calling the LoaderManager member of our Fragment. The two crucial methods we execute are as follows:

Both methods accept the loader ID and bundle data as arguments and the LoaderCallbacks<Cursor> implementation, which provides the following three methods to override: