74

My book, "Hello Android" gives this as a way of using a custom db helper, setting up a cursor, and then setting up an adapter as follows:

Cursor cursor
CustomDatabaseHelper test = new CustomDatabaseHelper(this);
try {
        cursor = getData();
        showData(cursor);
} finally {
        test.close();
}

With this however, everytime I need to refresh the data set, I need to keep running this block of code (which gets a bit difficult inside an onClick() for a button due to "this" not being available.

Is this the best way to refresh the data set, or should I look towards removing the .close and issue an adapter.notifyDataSetChanged()? If I do this, sometimes I get a force close as (and I can't remember at the moment) but sometimes it cannot Delete properly - I think this may be because the database is currently open and it tries to open again.

Should we also be declaring the variables for the Cursors, DatabaseHelpers and Adapter in the Class (outside of the OnCreate) so that they are accessible to all the functions?

I realise this is just poor programming at this stage, but Im trying to get some pointers as to the best way of doing things.

Simon
  • 1,385
  • 1
  • 11
  • 20
  • Just a sidenote: Things are a bit different if you use content providers and LoaderManager. See: http://stackoverflow.com/a/19657500/1087411 – Anderson Apr 13 '14 at 11:55

10 Answers10

104

You should use adapter.notifyDataSetChanged(). What does the logs says when you use that?

ThomasW
  • 16,981
  • 4
  • 79
  • 106
Macarse
  • 91,829
  • 44
  • 175
  • 230
  • 1
    Thanks Macarse, That does work, but only if I don't do a .close on the database helper. I think also what happens if I don't do the .close, the system tries to open too many databases and falls over. Should the database be open across the lifecycle of the activity then? – Simon Nov 16 '10 at 13:14
  • You should use http://developer.android.com/reference/android/app/Activity.html#startManagingCursor(android.database.Cursor) to manage your cursor inside an Activity. – Macarse Nov 16 '10 at 21:07
17

Simply add these code before setting Adapter it's working for me:

    listView.destroyDrawingCache();
    listView.setVisibility(ListView.INVISIBLE);
    listView.setVisibility(ListView.VISIBLE);

Or Directly you can use below method after change Data resource.

   adapter.notifyDataSetChanged()
Stefano Munarini
  • 2,711
  • 2
  • 22
  • 26
sravan
  • 5,303
  • 1
  • 31
  • 33
15

Best Way to Refresh Adapter/ListView on Android

Not only calling notifyDataSetChanged() will refresh the ListView data, setAdapter() must be called before to load the information correctly:

  listView.setAdapter(adapter);
  adapter.notifyDataSetChanged();
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
12

Following code works perfect for me

EfficientAdapter adp = (EfficientAdapter) QuickList.getAdapter();
adp.UpdateDataList(EfficientAdapter.MY_DATA);
adp.notifyDataSetChanged();
QuickList.invalidateViews();
QuickList.scrollBy(0, 0);
Hims
  • 293
  • 2
  • 11
2
adapter.notifyDataSetChanged();
Dinesh Saini
  • 335
  • 1
  • 12
2

If nothing works, just create the adapter instance again with the new set of results or the updated set of results. Then you can see the new view.

XYZAdapter adbXzy = new XYZAdapter(context, 0, listData);
xyzListView.setAdapter(adbXzy);

adbXzy.notifyDataSetChanged();
Vijay Kumar Kanta
  • 1,111
  • 1
  • 15
  • 25
0

If you are using LoaderManager try with this statement:

getLoaderManager().restartLoader(0, null, this);
adev
  • 367
  • 1
  • 3
  • 20
0

Perhaps their problem is the moment when the search is made in the database. In his Fragment Override cycles of its Fragment.java to figure out just: try testing with the methods:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_x, container, false); //Your query and ListView code probably will be here
    Log.i("FragmentX", "Step OnCreateView");// Try with it
    return rootView; 
}

Try it similarly put Log.i ... "onStart" and "onResume".

Finally cut the code in "onCreate" e put it in "onStart" for example:

@Override
public void onStart(){
    super.onStart();
    Log.i("FragmentX","Step OnStart");
    dbManager = new DBManager(getContext());
    Cursor cursor = dbManager.getAllNames();
    listView = (ListView)getView().findViewById(R.id.lvNames);
    adapter = new CustomCursorAdapter(getContext(),cursor,0);// your adapter
    adapter.notifyDataSetChanged();
    listView.setAdapter(adapter);
}
Robert
  • 7,394
  • 40
  • 45
  • 64
0

Just write in your Custom ArrayAdaper this code:

private List<Cart_items> customListviewList ;

refreshEvents(carts);

public void refreshEvents(List<Cart_items> events)
{
    this.customListviewList.clear();
    this.customListviewList.addAll(events);
    notifyDataSetChanged();
}
Harsh Wardhan
  • 2,110
  • 10
  • 36
  • 51
-4

just write in your Custom ArrayAdaper this code:

public void swapItems(ArrayList<Item> arrayList) {
    this.clear();
    this.addAll(arrayList);
}
Yerassyl
  • 45
  • 1
  • 7