I too have tried invalidate(), invalidateViews(), notifyDataSetChanged(). They all might work in some particular contexts but it did not do the job in my case.
In my case, I had to add some new rows to the list and it just does not work. Creating a new adapter solved the issue.
While debugging, I realized that the data was there but just not rendered. If invalidate() or invalidateViews() does not render (which it is supposed to), I don't know what would.
Creating a new Adapter object to refresh modified data does not seem to be a bad idea. It definitely works. The only downside could be the time consumed in allocating new memory for your adapter but that should be OK assuming the Android system is smart enough and takes care of that to keep it efficient.
If you take this out of the equation, the flow is almost same as to calling notifyDataSetChanged. In the sense, the same set of adapter functions are called in either case.
So we are not losing much but gaining a lot.