akshayt23 akshayt23 - 11 days ago 5
Android Question

Using Custom Adapter with CursorLoader

I'm trying to use

CursorLoader
to fetch data from my
ContentProvider
off the UI thread. I then use it to populate my list view. I was using
SimpleCursorAdapter
before and it works all fine. But now I want to have different views for the list view rows depending upon the data.

So I wrote a custom adapter extending the base adapter.

public class CustomAdapter extends BaseAdapter {

private Context mContext;
private LayoutInflater mInflater;

public CustomAdapter(Context context) {
mContext = context;
mInflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
return 10;
}

@Override
public View getView(int i, View view, ViewGroup viewGroup) {
Log.d("CustomAdapter", "Check" + i + 1);
if (view == null) {
view = mInflater.inflate(R.layout.listview_text_layout, viewGroup, false);
//if(text) load text view
//else load image view
}

return view;
}
}


But to get anything to display, the
getCount()
method should return a value greater than
0
.

How can I get the number of items loaded by the
CursorLoader
so that all elements be displayed? Currently, I'm just returning
10
to make it work but that's obviously not the right way to do it.

Here's my
Fragment
class which implements
CursorLoader
:

public class MessageFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {

private AbsListView mListView;
private CustomAdapter mAdapter;
...

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_message, container, false);

getLoaderManager().initLoader(MESSAGES_LOADER, null, this);

// Set the adapter
mListView = (AbsListView) view.findViewById(android.R.id.list);
mListView.setAdapter(mAdapter);

return view;
}


@Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String[] projection = {MessageEntry._ID, MessageEntry.MESSAGE_DATA, MessageEntry.MESSAGE_TIMESTAMP};

switch (i) {
case MESSAGES_LOADER:
return new CursorLoader(
getActivity(),
Uri.parse("content://com.rubberduck.dummy.provider/messages"),
projection,
null,
null,
null
);
default:
return null;
}
}
}


Also, in my
getView()
method, I need to access the data so that I can select which layout to inflate. I know we can pass a List of the data to the Custom Adapter, but how do we do it when the data is actually loaded by
CursorLoader
?

Answer

Instead of extending BaseAdapter, you could extend CursorAdapter.

When onLoadFinished is called you only need to call swapCursor. You don't need to override getCount(). The super already takes care of returning the correct value.