Sam Starling
Sam Starling

Reputation: 5378

Android: ListView with dynamic colours

I'm trying to make a ListView which represents a list of train lines, each with a different colour. So at the moment I have this:

public class TrainOverview extends ListActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,
            R.layout.list_item, R.id.label, TrainLines.lines);
        this.setListAdapter(arrayAdapter);
    }
}

The list_item XML simply consists of two text labels in a linear layout, one of which I want to be able to change the colour of dynamically. TrainLines.lines is just a String[] at the moment, but I'd like to make it a very simple class with name and colour attributes. Then, I'd like to be able to create a ListView that shows the name of the train line, and the appropriate colour.

What's the best way to achieve this? I hope my question makes sense!

Upvotes: 0

Views: 94

Answers (2)

mgibson
mgibson

Reputation: 6213

I would recommend extending BaseAdapter, it is relatively easy to do and very useful when it comes to various Views / row layouts (including changing colour of TextView)

The methods getViewTypeCount() and getItemViewType(position) can be easily overriden to give you as many different row layouts as you like.

This may not be your goal at all but is a handy thing to know.

However, I believe you will need a custom BaseAdapter, in which you override the getView(int position, View convertView, ViewGroup parent) method.

This would allow you to access theTextView for each row as you mentioned above. A good way to go about this is by implementing the ViewHolder pattern.

You could create a simple ViewHolder object ie.

private static class ViewHolder
{
     TextView textView;
}

Then use that in your overriden getView()

    // Get that view
    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {               
        if (convertView == null)
        {
            if (getItemViewType(position) == 0)
            {
                convertView = inflater.inflate(R.layout.rowlayouta, null);
                viewHolder = new ViewHolder();
                viewHolder.textView = (TextView) convertView.findViewById(R.id.tvCommonText1);
                convertView.setTag(viewHolder);
            }
            else
            {
                convertView = inflater.inflate(R.layout.rowlayoutb, null);
                viewHolder = new ViewHolder();
                viewHolder.textView = (TextView) convertView.findViewById(R.id.tvCommonText2);
                convertView.setTag(viewHolder);
            }
        }

        else 
            viewHolder = (ViewHolder) convertView.getTag(); // Or if View is existing

        viewHolder.textView.setText(strings.get(position));

        return convertView;         
    }   

That's just an example of how I inflated two different row layouts, you could just take out the first else.

You can see that if there is now ViewHolder object assigned to that row, a new ViewHolder object is created, its TextView is set to the reference of the current convertView - effectively the current rows View. Then the ViewHolder object which now contains reference to that specific rows TextView is basically attached to that convertView / row using the setTag(object) method.

If it already has a tag, that tag is got using the getTag() method instead of creating a new object with new references. MOST importantly, no new view is inflated, the old one is just reused.

This then allows you to set what TextView properties you want by referring to the current ViewHolder object which holds reference to that specific TextView.

As you can see I changed the text to each TextView as I went along to reflect which row / convertView was being displayed. (Pretty useful in itself). All you need to do there is refer to the current ViewHolder in the same way and use the setTextColor() method.

Maybe that was a bit drawn out. But hopefully with that you will be able to implement what you are asking about and you know why it is a good implementation.

P.S. For more info on how ListViews and adapters come together (thinking of the getView() method here), this tutorial is pretty helpful..

http://android.amberfog.com/?p=296

Upvotes: 3

Adam Arold
Adam Arold

Reputation: 30538

I think that you can use the setTextColor() method declared in the TextView class. Check out the documentation here.

I assume that by dynamic colours you mean programmatically modifying the colors of your TextViews.

If you are looking for a custom array adapter please refer to this tutorial.

Upvotes: 0

Related Questions