1

I populate a ListView with a SimpleAdapter. Immediately after doing so, I have a function that tries to loop over the child views to set their background color programmatically. The problem is that the ListView may not have any children immediately after listView.setAdapter() is called. I don't know which callback to stick my function on.

        // A HashMap to store the values for the ListView rows
    List<HashMap<String, String>> aList = new ArrayList<HashMap<String, String>>();

    for (int i = 0; i < steps.length; i++) {
        HashMap<String, String> hm = new HashMap<String, String>();
        hm.put("txt", steps[i]);
        hm.put("icon", Integer.toString(step_images[i]));
        aList.add(hm);
    }

    // Keys used in Hashmap
    String[] from = {"icon", "txt"};

    // Ids of views in layout
    int[] to = {R.id.icon, R.id.txt};

    // Instantiating an adapter to store each items
    // R.layout.listview_steps defines the layout of each item
    SimpleAdapter adapter = new SimpleAdapter(getBaseContext(), aList, R.layout.listview_steps, from, to);

    // Setting the adapter to the listView
    listView.setAdapter(adapter);



    //fixme after the listView adapter is set, the listView may not have any children immediately.
    //I'm not sure which callback to use to properly call refreshStepsListView().. So I'm hacking it and I just wait 250ms
    (new Handler())
            .postDelayed(
                    new Runnable() {
                        public void run() {
                            refreshStepsListView();
                        }
                    }, 250);
Jesse Skrivseth
  • 481
  • 2
  • 13

3 Answers3

1

Don't need a callback. Do it live

public class ColoredAdapter extends SimpleAdapter {

     ColoredAdapter(...) {
         super(context, list,  reslayout, from, to);
    } 

    getView(...) {
        // set colors here 
   } 

Or you could create a list of a Step class rather than a Hashmap, plus use an ArrayAdapter<Step>

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
  • Thanks! This should work. The colors are driven by state flags in another model, but I'll work that out. I'm new to Android. I need to spend more time with Adapters in general. – Jesse Skrivseth Sep 01 '17 at 03:52
1

From what I understand. You just want to change the background of each item inside the listview.

First, define you class item for Adapter.

    public class Item {
      private String mTitle;
      private String mBackgroundColor;

      public void setTittle(String title){
        this.mTitle = title;
      }

      public void setBackgroundColor(int color){
        this.mBackgroundColor= color;
      }

      public void getTitle (){
        return this.mTitle;
      }


      public void getBackgroundColor(){
        return this.mBackgroundColor;
      }
   }

Then use ArrayAdapter instead of SimpleAdapter See this sample Here

Make sure inside getView() of your ArrayAdapter, you have set item background color from item.getBackgroundColor()

itemView.setBackgroundResource(item.getBackgroundColor());

When you want to change the background color, you can just set new color to which item item.setBackgroundColor(newColor) and call adapter.notifyDataSetChanged() to refresh the adapter.

THANN Phearum
  • 1,969
  • 22
  • 19
0

Do your background coloring work inside your adapter. You can simply extend SimpleAdapter and get access to the views as they are created. In the adapter is where you are expected to do any view manipulation logic.

Iterating over the children is not advised and will result in bugs, unmaintainable code, and bad performance.

public class ColorAdapter extends SimpleAdapter {

    public ColorAdapter(Context context, 
                        List<? extends Map<String, ?>> data, 
                        int resource, 
                        String[] from, 
                        int[] to) {

        super(context, data, resource, from, to);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = super.getView(position, convertView, parent);
        view.setBackgroundColor(Color.RED);
        return view;
    }
}
Dave Thomas
  • 3,667
  • 2
  • 33
  • 41