How to change backgrounds for specific rows using SimpleCursorAdapter - android

I'm trying to create a listview generated from information out of my SQLite DB. I currently have the code set up to just display each row accordingly and populate 3 textviews with data. I would like to be able to use some sort of If statement to check to see if one of values is "Room1" and then set the background of that row to a certain color.
This way each row in the list will have a different background based on what "room" the data is for.
I have tried extending SimpleCursorAdapter but I am a bit lost on how to get what I want out of it.
Here is what I have currently for the SimpleCursorAdapter:
Cursor notesCursor = myDbHelper.fetchDayPanelNotes(type, day);
startManagingCursor(notesCursor);
String[] from = new String[]{DataBaseHelper.KEY_NAME, DataBaseHelper.KEY_ROOM, DataBaseHelper.KEY_TIME};
int[] to = new int[]{R.id.text1, R.id.text2, R.id.text3};
SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.main_row, notesCursor, from, to);
setListAdapter(notes);

You should override the getView method of your adapter:
SimpleCursorAdapter notes = new SimpleCursorAdapter(
this, R.layout.main_row, notesCursor, from, to)
{
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
final View row = super.getView(position, convertView, parent);
if (position % 2 == 0)
row.setBackgroundResource(android.R.color.darker_gray);
else
row.setBackgroundResource(android.R.color.background_light);
return row;
}
};
and set the background of the row based on the position (is it odd or even).

This should do it.
Thanks to this post, I had exact same problem but after going through this, problem solved as shown below,
SimpleCursorAdapter notes = new SimpleCursorAdapter(this, R.layout.notes_row, mNotesCursor, from, to)
{
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
cursor.moveToPosition(position);
String s = cursor.getString(mursor.getColumnIndex("roomnumber"));
final View row = super.getView(position, convertView, parent);
if (s.equalsIgnoreCase("room1"))
row.setBackgroundColor(Color.parseColor("#480000"));
else if (s.equalsIgnoreCase("room2"))
row.setBackgroundColor(Color.parseColor("#000040"));
else
row.setBackgroundColor(Color.parseColor("#004000"));
return row;
}
};
setListAdapter(notes);

I implement SimpleCursorAdapter.ViewBinder on my Activity then override setViewValue...
public class MyActivity extends Activity
implements SimpleCursorAdapter.ViewBinder {
SimpleCursorAdapter myAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
// Initialize myAdapter
myAdapter.setViewBinder(this);
}
#Override
public boolean setViewValue(View view, Cursor cursor, int column) {
// Put code to process row data here
}
}

I would recommend extending BaseAdapter, populating your list data manually and keeping a local copy of that data in your adapter class. Then when you implement the getView(...) method you can use the position or ID of the View you're generating to fetch the corresponding data to check against "Room1," and alter the View you return based on that comparison.
The answer by rekaszeru has exactly the right idea, but it sounds like you'll need more information than the position and ID, which is why I recommend going a level lower and implementing BaseAdapter directly.

Related

Android, color an item of a listView

I have a listView that uses the
SimpleAdapter
Each element of this list contains 2 textView
I wanna color(change the backgroud color) an item of this list, how can I do?
To change the background color of the whole view (not just the textview) and using a very simplistic approach you would have this call:
private void setupAdapter() {
SimpleAdapter adapter = new SimpleAdapter(this, data, resource, from, to) {
public View getView(int position, View convertView, ViewGroup parent) {
View superView = super.getView(position, convertView, parent);
superView.setBackgroundColor(R.color.black); // or whatever color
return superView;
};
};
// use the adapter as: myListView.setAdapter(adapter);
}
this could be done using android selector (xml). see the example here
One way to create custom SimpleAdapter class which overrides getView method and there you make an background change depending - I guess - on some condition.

How to give different styles to list items based on a certain condition?

I'm building a list of strings with an adapter, how can I apply a different layout property to these items based on a certain condition?
For example, suppose that you need to check if the text of a list item contains a specific word and then, based on the result of the test, you want to, say, increase or decrease its margin (if this can make any sense :D ).
create a adapter like the following. here only background colors are changed, try changing layouts there depending on u r condition....
public class SpecialAdapter extends SimpleAdapter {
private int[] colors = new int[] { 0x30FF0000, 0x300000FF };
public SpecialAdapter(Context context, List<HashMap<String, String>> items, int resource, String[] from, int[] to) {
super(context, items, resource, from, to);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
int colorPos = position % colors.length;
view.setBackgroundColor(colors[colorPos]);
return view;
}
}
for more details check this link http://eureka.ykyuen.info/2010/03/15/android-%E2%80%93-applying-alternate-row-color-in-listview-with-simpleadapter/
You can use the ContextThemeWrapper in order to provide different themes based on your certain conditions.

display information, that is contained of an object, to a ListView

I'm trying to display information about an object, concretely a customer. I mean name, last name, telephone number, adress, .... that is the result by a query on my database.
I want to display this on a ListView, so better if my activity inherit of a ListActivity because ListView is self-contained by default.
I do the next: I have a class called Customer that saves all information by the query (Cursor) that only return one record(customer) and I don't know how to pass this object ,I don't find the most appropriate adapter.
Can I do this by this way or I must convert this object into an ArrayList that contains all information and, in fact, use ArrayAdapter for my adapter?
Anyone knows how to do this??
Thanks.
Once you have your cursor queried you should do something like this
String[] from = new String[]{"FirstName"};
int[] to = new int[]{R.id.row};
SimpleCursorAdapter sca = new SimpleCursorAdapter(this, R.layout.row_item, cur, from, to);
setListAdapter(sca);
check here the documentation for SimpleCursorAdapter.
If you need to do something more complicated with your views you should implement your own custom Cursor adapter:
public class ExampleCursorAdapter extends CursorAdapter {
public ExampleCursorAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView summary = (TextView)view.findViewById(R.id.summary);
summary.setText(cursor.getString(
cursor.getColumnIndex(ExampleDB.KEY_EXAMPLE_SUMMARY)));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.item, parent, false);
bindView(v, context, cursor);
return v;
}
}
And finally, I can find the solution it would be. I'm going to tell you how I did.
I wanted to display details customer by this way:
row 1-> Name: name_value
row 2-> Last Name: lastname_value
row 3-> Phone: phone_value
...
N. n row -> n_field: n_value
Fields that describe what value is going to show, i mean "Name:", "Last Name:", "Phone:", ...
I put all this values on a string-array . I captured that by a String [] .
Values, show proper value next the correct field. I put all this inside a ArrayList
and next only have to write the proper adapter:
This Activity inherit ListActivity, ListView by default.
SimpleCursorAdapter is not proper because we have to pass the cursor as argument of this adapter but my Cursor only returns only one result, only one record .
And CursorAdapter is refused by the same reason. What can I do next? ArrayAdapter :
public class DetalleClienteAdapter extends ArrayAdapter<String>
{
private String[] campos_cliente;
private ArrayList<String> detalles_cliente;
public DetalleClienteAdapter(Context contexto, int layout, ArrayList<String> detalles)
{
super(contexto,layout,detalles);
//mInflater = LayoutInflater.from(contexto);
// LOS VALORES DE LOS CAMPOS:
detalles_cliente = detalles;
// CAMPOS DE DETALLES: nombre, apellidos, etc...
android.content.res.Resources res = getResources();
campos_cliente = res.getStringArray(R.array.array_detalle_cliente);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
// TODO Auto-generated method stub
//return super.getView(position, convertView, parent);
LayoutInflater inflater= getLayoutInflater();
View fila = inflater.inflate(R.layout.detalles_cliente, parent, false);
TextView campo =(TextView)fila.findViewById(R.id.detalles_campo);
TextView valor =(TextView)fila.findViewById(R.id.detalles_valor);
campo.setText(campos_cliente[position]);
valor.setText(detalles_cliente.get(position));
return fila;
}
}
Now I'm going to write a more efficient adapter, with ViewHolder. What is your opinion about that?
Thanks.

Android selection issue in ListView

I have a ListView (set to CHOICE_MODE_SINGLE)
I have a SimpleCursorAdapter who fill my ListView. Now i work on selection.
serviceListView.setAdapter(
new SimpleCursorAdapter(this, R.layout.service_listitem, cursor, new String[] { "name" }, new int[] { R.id.service_name }) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
final View renderer = super.getView(position, convertView, parent);
if (position == newSelectedPosition) {
renderer.setBackgroundResource(R.layout.list_view_layer_list);
} else {
renderer.setBackgroundResource(android.R.color.transparent);
}
return renderer;
}
}
);
So i want when i select a row my layout to be applied. This works fine.
But in some cases when i push for 2-3 secs a row and then drag a little bit and release the row i obtain 2 rows selected.
I try several ways to get ride of the initial selection, overwriting OnTouchListener, OnScrollListener, OnLongClickListener. No results.
Any help is welcome
Thanks
Have you tried calling notifyDataSetChanged() on your Adapter after the selection has been changed? That should cause all the rows to be rebound again, and all the views (except for the selected one) to revert back to the transparent background.
I quit this implementation.
I will try to "simulate" ListView by using a ScrollView with TextView-s for each row

Android, using SimpleCursorAdapter to set colour not just strings

I have a simple cursor adapter set on a list in my application as follows:
private static final String fields[] = {"GenreLabel", "Colour", BaseColumns._ID};
datasource = new SimpleCursorAdapter(this, R.layout.row, data, fields, new int[]{R.id.genreBox, R.id.colourBox});
R.layout.row consists of two TextViews (genreBox and colourBox). Rather than setting the content of the TextView to the value of "Colour" , I would like to set its background colour to that value.
What would I need to do to achieve this?
Check out SimpleCursorAdapter.ViewBinder.
setViewValue is basically your chance to do whatever you wish with the data in your Cursor, including setting the background color of your views.
For example, something like:
SimpleCursorAdapter.ViewBinder binder = new SimpleCursorAdapter.ViewBinder() {
#Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
String name = cursor.getColumnName(columnIndex);
if ("Colour".equals(name)) {
int color = cursor.getInt(columnIndex);
view.setBackgroundColor(color);
return true;
}
return false;
}
}
datasource.setViewBinder(binder);
Update - if you're using a custom adapter (extending CursorAdaptor) then the code doesn't change a whole lot. You'd be overriding getView and bindView:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView != null) {
return convertView;
}
/* context is the outer activity or a context saved in the constructor */
return LayoutInflater.from(context).inflate(R.id.my_row);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
int color = cursor.getInt(cursor.getColumnIndex("Colour"));
view.setBackgroundColor(color);
String label = cursor.getString(cursor.getColumnIndex("GenreLabel"));
TextView text = (TextView) findViewById(R.id.genre_label);
text.setText(label);
}
You're doing a bit more manually, but it's more or less the same idea. Note that in all of these examples you might save on performance by caching the column indices instead of looking them up via strings.
What you're looking for requires a custom cursor adapter. You can subclass SimpleCursorAdapter. This basically give access to the view as its created (although you'll be creating it yourself).
See this blog post on custom CursorAdapters for a complete example. Particularly, I think you'll need to override bindView.

Categories

Resources