I'm writing a tiny messaging app and I've recently encountered this problem.
I've got a ListFragment
subclass, which implements a CursorLoader
callback. The built-in ListView
is bound to a SimpleCursorAdapter
. Every row view in this list has a level drawable as a background. I'd like to switch between the levels depending on the database info (whether the message was sent or not).
My question is how do you change the background of a single row in this case? Do I have to access it through the adapter? I'm pretty sure this should be done in the onLoadFinished
method. But this code gives me NullPointerException
. If you could point me in the right direction, I would be really grateful.
public class MessagesFragment extends ListFragment implements
LoaderManager.LoaderCallbacks<Cursor>{
private static MessagesFragment fragment;
private static MainActivity activity;
private static SimpleCursorAdapter adapter;
public static MessagesFragment getInstance() {
if (fragment == null)
fragment = new MessagesFragment();
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = (MainActivity) getActivity();
adapter = new SimpleCursorAdapter(activity, R.layout.list_item, null,
new String[] {DataProvider.KEY_NUMBER, DataProvider.KEY_MESSAGE, DataProvider.KEY_TIME},
new int [] {R.id.item_field_number, R.id.item_field_message, R.id.item_field_time}, 0);
setListAdapter(adapter);
getLoaderManager().initLoader(0, null, this);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_messages, null);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
activity.showDetails(Long.valueOf(id).intValue());
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(activity, DataProvider.CONTENT_URI, null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
adapter.swapCursor(data);
while (data.moveToNext()) {
int id = data.getInt(data.getColumnIndex(DataProvider.KEY_ID));
int sent = data.getInt(data.getColumnIndex(DataProvider.KEY_SENT));
this.getListView().getChildAt(id).getBackground().setLevel(sent);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);
}
}
This should Help!
public class SampleAdapter extends SimpleCursorAdapter {
private LayoutInflater inflater;
private Cursor cursor;
private Context context;
public SampleAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
this.context = context;
cursor = c;
inflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return cursor == null ? 0 : cursor.getCount();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (cursor != null) {
ViewHolder holder;
cursor.moveToPosition(position);
if (convertView == null) {
convertView = inflater.inflate(R.layout.list_item, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
convertView.getBackground().setLevel(cursor.getInt(cursor.getColumnIndex(DataProvider.KEY_SENT)));
holder.number.setText(cursor.getString(cursor.getColumnIndex(DataProvider.KEY_NUMBER)));
holder.message.setText(cursor.getColumnIndex(DataProvider.KEY_MESSAGE)));
holder.time.setText(cursor.getColumnIndex(DataProvider.KEY_TIME)));
}
return convertView;
}
@Override
public Cursor swapCursor(Cursor c) {
cursor = c;
return super.swapCursor(c);
}
private class ViewHolder {
TextView number;
TextView message;
TextView time;
public ViewHolder(View view) {
number = (TextView) view.findViewById(R.id.item_field_number);
message = (TextView) view.findViewById(R.id.item_field_message);
time = (TextView) view.findViewById(R.id.item_countries_time);
}
}
}