问题
I have a list of orders in SQLite which vary in status: assigned, loaded, delivered. I'd like for each of those orders, when displayed in the list, to have a different colored background. So far, I haven't found a good way to do this.
I've found plenty of discussions on how to change the background color of list items based on the position, but none based on data content. I've also found lots of discussions on how to change the color that's used to highlight an item that is selected. These don't help me.
The only methods I come up with for solving my problem involve running through the entire list, after it's been created by the adapter, and setting the background on each item. It's kludgy and wasteful. I'm hoping there's a more efficient method that would let the background be changed in the adapter as the list is being created from the cursor.
I'm sure there's a better way. I'm just too new to Android to know it.
I really appreciate the responses so far. I'm doing my best to incorporate them, but I'm still not having success. Here's what I've just tried, based on the answers I've gotten and the research I've done.
public class OrderListAdapter extends SimpleCursorAdapter {
private static final String TAG = "SimpleCursorAdapter";
Context _context = null;
int layoutResourceId = 0;
public OrderListAdapter(Context context, int layout, Cursor c,
String[] from, int[] to, int flags) {
super(context, layout, c, from, to, flags);
_context = context;
}
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
String tag = TAG + ".getView()";
Log.d(tag,"in getView()");
if (view == null) {
LayoutInflater inflater = ((Activity)_context).getLayoutInflater();
view = inflater.inflate(R.layout.fragment_order_list_row, null);
}
setRowColor(view);
return view;
}
private void setRowColor(View view) {
String tag = TAG + ".setRowColor()";
Cursor cursor = getCursor();
int col = cursor
.getColumnIndex(DBContract.DeliveryOrderTable.ENROUTE_FLAG);
String enroute_flag = cursor.getString(col);
Log.d(tag, "enroute_flag = [" + enroute_flag + "]");
col = cursor
.getColumnIndex(DBContract.DeliveryOrderTable.DELIVERED_DATETIME);
String deliveredDateStr = cursor.getString(col);
Log.d(tag, "deliveredDateStr = [" + deliveredDateStr + "]");
int bgColorId = 0;
if (!deliveredDateStr.equals("")) {
bgColorId = R.color.bg_status_delivered_color;
Log.d(tag, "Setting to delivered color");
} else if (enroute_flag.startsWith("T") || enroute_flag.startsWith("Y")) {
Log.d(tag, "Setting to enroute color");
bgColorId = R.color.bg_status_enroute_color;
} else {
Log.d(tag, "Setting to assigned color");
bgColorId = R.color.bg_status_assigned_color;
}
view.setBackgroundColor(_context.getResources().getColor(bgColorId));
}
}
Unfortunately, this doesn't work. If I don't make the call to super.getView(), I wind up with no data in the fields, obviously, since I don't explicitly make the transfers, but I figured I could just modify the returned view.
My traces show me that I am reading the data, but the background color is not changing.
It appears that the view I'm trying to change is the LinearLayout, but changing the background color doesn't seem to work.
Got it! Make sure to make the backgrounds of all the child views transparent.
回答1:
if you are using any custom adapter for listview then, you will have a method getView(), in that just call a method before returning, and pass the view(which is returning) and data depending on you want to change the color of the row.
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
if (view == null) {
LayoutInflater vi = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = vi.inflate(R.layout.list_item_var, null);
}
TextView varView = (TextView) view.findViewById(R.id.var);
TextView valueView = (TextView) view.findViewById(R.id.value);
VarDetails var = _data.get(position);
setRowColor(view, var.getVar());
varView.setText(var.var);
valueView.setText("Value: " + var.value);
return view;
}
private void setRowColor(View view, String var) {
if("assigned".equalsIgnoreCase(var)){
view.setBackgroundColor(Color.rgb(255,0,0));
}else if("loaded".equalsIgnoreCase(var)){
view.setBackgroundColor(Color.rgb(0,255,0));
}else if("delivered".equalsIgnoreCase(var)){
view.setBackgroundColor(Color.rgb(0,0,255));
}
}
please change in method depending on you data type.
回答2:
I would say try to extend CursorAdapter for binding your database with a ListView. And then you can override ListView.dispatchDraw() to customize your Paint object.
Or maybe it's helpful to check this: Customizing Android ListView Items with Custom ArrayAdapter
It uses different images based on weather status. Porting to your problem, you may use 9-patch or programmatically created Drawables as backgrounds, rather than changing stuff in Paint.
来源:https://stackoverflow.com/questions/16176398/how-can-i-change-the-background-color-of-list-items-based-on-the-data-being-disp