10

I have a GridView with each cell containing some text, and I want to be able to set the background colour of individual cells.

The XML for my GridView is:

<GridView android:id="@+id/students_grid" android:layout_width="fill_parent" android:layout_height="fill_parent" android:numColumns="6" android:gravity="center" android:stretchMode="columnWidth"> </GridView> 

The code for my GridView is:

GridView gridView = (GridView) findViewById(R.id.students_grid); ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, student_array); gridView.setAdapter(adapter); 

I had hoped I would be able to set the background colour of individual cells using:

gridView.getChildAt(random_student).setBackgroundColor(Color.parseColor("#18A608")); 

However, this throws a null pointer exception, and on further examination it seems that gridview.getChildCount() returns 0. I have seen that gridview.getCount returns the number of items in the gridview correctly, but this doesn't help me to set the background colour of individual cells.

Any ideas where I go next?

0

3 Answers 3

10

The key to solving this problem is to first understand how ListView and GridView work. GridView creates and destroys child views as you scroll up and down. If you can't see an item in a GridView that means there is no child view for it, it will be created when the user actually scrolls to it. GridView uses an Adapter to create the views and GridView recycles views when they go offscreen and asks the Adapter to reuse the recycled views for new views that come on screen. The Adapter usually inflates a resource layout to create new views.

So what this means is that GridView will call getView(...) on the Adapter each time it wants to display a child view on screen, it may pass a recycled View called convertView.

The solution is to override getView(...), call super to let the Adapter create and populate the view with data from the String array normally but add a bit of code at the end before we give the view back to GridView that sets the color of the view.

new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, student_array) { @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); int color = 0x00FFFFFF; // Transparent if (someCondition) { color = 0xFF0000FF; // Opaque Blue } view.setBackgroundColor(color); return view; } }; 
Sign up to request clarification or add additional context in comments.

Comments

5

Main activity where you have to create array of hexadecimal color code and and pass to custom adapter class

public class MainActivity extends Activity { GridView gridView; String[] gridColor ={ "#008B8B", "#00FF00", "#48D1CC", "#556B2F", "#696969", "#6B8E23", "#8FBC8F", "#AFEEEE", "#B8860B", "#BDB76B", "#D8BFD8", "#DEB887", "#FFFF00", "#FFF0F5", "#EE82EE", "#DC143C", "#C0C0C0" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Grid adapter = new Grid(MainActivity.this,gridColor); gridView=(GridView)findViewById(R.id.grid_view); gridView.setAdapter(adapter); gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(MainActivity.this, "You Clicked On " +gridcolor[+ position], Toast.LENGTH_SHORT).show(); } }); } } 

Custom adapter code should be like this where color codes are parsed.

public class Grid extends BaseAdapter { private Context mContext; private final String[] menu; private final int[] Imageid; private final String[] gridcolor; public Grid(Context context,String[] menu,int[] Imageid,String[] gridcolor) { mContext=context; this.gridcolor=gridcolor; } @Override public int getCount() { return gridcolor.length; } @Override public Object getItem(int i) { return null; } @Override public long getItemId(int i) { return 0; } @Override public View getView(int i, View view, ViewGroup viewGroup) { View grid; LayoutInflater inflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (view == null) { grid = new View(mContext); grid = inflater.inflate(R.layout.grid_layout, null); grid.setBackgroundColor(Color.parseColor(gridcolor[i])); } else { grid = view; } return grid; } } 

Comments

-1

You need to create a custom layout and use it in your adapter instead of android.R.layout.simple_list_item_1. For example:

<TextView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceListItemSmall" android:gravity="center_vertical" android:paddingLeft="?android:attr/listPreferredItemPaddingLeft" android:paddingRight="?android:attr/listPreferredItemPaddingRight" android:minHeight="?android:attr/listPreferredItemHeightSmall" android:background="#18A608" /> 

(I simply copied the latest version of simple_list_item_1.xml and added the new background color at the end.)

Save this as grid_layout.xml in res/layout and change your adapter's constructor to:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.grid_layout, student_array); 

3 Comments

Thanks. That works for initialising all of the cells when the screen is created. But I also need to access and change cells dynamically. Is there a way to reference individual cells at runtime in order to change their colour?
(Sorry, I just found your response.) Yes, but do you want to highlight just one cell or every cell that matches a criteria (like every third cell or every student that is failing)?
@Mark__C yes, override BaseAdapter as suggested in the SDK.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.