How to force redraw of listview?
Asked Answered
D

3

8

This question is a little different from others of a similar title. I am not trying to update the data in the list, I am trying to update the look of the list.

My app is fragment based using the support library. I have a PreferenceActivity where I allow the user to set the colors they would like for the text in a list (the adapter reads the preference and sets the colors). This is working as expected for the most part.

The issue I'm having is as follows. When I have the list on the screen (it is a ListFragment) and pull up the menu, choose Preferences and make a change to the color preference. Upon return to the list from the PreferenceActivity, I cannot seem to get the list to redraw itself with the new color specified.

If I navigate away from the list and come back to it, it is regenerated with the new color.

I am trying to use onResume to make the change. The code I currently have (that doesn't appear to do anything to the list, but changes the header color as it should):

@Override
public void onResume() {
    super.onResume();
    header.setTextColor(MyApplication.header);
    line.setBackgroundColor(MyApplication.header_line);
    subheader.setTextColor(MyApplication.header);
    getListView().invalidateViews();
}

I have tried invalidateViews and invalidate. In desperation I tried calling notifyDataSetChanged on the adapter even though there was no change to the data itself. Nothing seems to work.

Am I missing something obvious, or is there no way to do this?

EDIT

The 'getView` method from my adapter:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null)
        convertView = View.inflate(context, layout, null);
    View row = convertView;
    c.moveToPosition(position);
    TextView first = (TextView) convertView.findViewById(R.id.ListItem1);
    TextView second = (TextView) convertView.findViewById(R.id.ListItem2);
    TextView third = (TextView) convertView.findViewById(R.id.ListItem3);
    TextView fourth = (TextView) convertView.findViewById(R.id.ListItem4);

    DecimalFormat df = new DecimalFormat("0.00");
    Double hold = Double.valueOf(c.getString(3));
    Double qty = Double.valueOf(c.getString(1));
    Double total = hold * qty;

    String color = "#FF00FF";
    first.setText(c.getString(2));
    first.setTextColor(MyApplication.shoplistitem_name);
    second.setText(c.getString(4));
    second.setTextColor(MyApplication.shoplistitem_desc);
    third.setText(c.getString(1));
    third.setTextColor(MyApplication.shoplistitem_qty);
    fourth.setText("$" + df.format(total));
    fourth.setTextColor(MyApplication.shoplistitem_desc);

    if (strikethroughState[position] == 1) {
        first.setPaintFlags(first.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        second.setPaintFlags(second.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        third.setPaintFlags(third.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        fourth.setPaintFlags(third.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        row.setBackgroundColor(MyApplication.shoplistitem_checked);
    } else {
        first.setPaintFlags(first.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        second.setPaintFlags(second.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        third.setPaintFlags(third.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        fourth.setPaintFlags(third.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        row.setBackgroundResource(R.color.black);
    }
    return (row);
}
Draper answered 20/6, 2012 at 15:45 Comment(0)
C
10

notifyDataSetChanged() should certainly be working for you. How are you handling the preference change? If you're just committing the preference to the SharedPreferences then it's never updating the static MyApplication variable. Can you post the code you're using to set the preference? If you're not using it, set an onPreferenceChangedListener() for the color preference to set that static variable when it is changed.

Contrary answered 20/6, 2012 at 18:10 Comment(1)
Well... this pointed the way to my finding the problem... and I feel incredibly stupid. I was calling MyApplication.setPreferences. The method is MyApplication.setPrefs. sighDraper
S
3

You should call notifyDataSetChanged() on your adapter.

Skitter answered 20/6, 2012 at 16:12 Comment(5)
Did you miss the part in my post where I said I tried that and it didn't work? Just tried it again, same. No redraw of the views.Draper
can you post your getView() method from the adapter?Skitter
Where in getView() do you set the colour of the text to a colour from preferences?Skitter
first.setTextColor(MyApplication.shoplistitem_name);. When the PreferenceActivity exits it calls a method from MyApplication that reads all the preferences into static variables to be used throughout the app.Draper
Does hasStableIds() return false? If not, what happens when you return false in hasStableIds()?Skitter
S
0

Invalidate, invalidateviews, notifyDatasetChanged, nothin worked for me! To just update the listview (with cursoradapter) I just do:

cur = db.rawQuery( "SELECT * FROM ssnt WHERE mid = 1000" ); //optional, initial query
adapter.changeCursor(cur); // or swapCursor(), cur is the initial and the only cursor 

But to have the correct backgrounds color, drawable, underline text, I just do:

cur = db.rawQuery( "SELECT * FROM ssnt WHERE mid = 1000" );
adapter.changeCursor(cur);
list.setAdapter(adapter);    //just like I did oncreate

I dont like Barak solution cos it seems heavy weight, and executes code when not needed.

Saliferous answered 22/11, 2014 at 1:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.