Android ListView update

I have a Listview that pulls and displays data from sqlite database. The data in the first column of the database is displayed in the Listview , and when the Activity button is clicked, the rest of the column associated with the first column is displayed. When data is being edited, Listview needs to be updated to reflect this, but it does not show updates if the application is not restarted.

I tried calling, notifyDataSetChanged() and startActivityForResult() in my onResume() method, but that did not work. Which method should I use to update Listview in my current code?

I understand that a SimpleCursorAdapter can be used, and I tried to implement this code without success. I am new and need some real code to figure out what needs to be done.

 public class LoginList extends Activity implements OnClickListener, OnItemClickListener { private ListView loginList; private Button webLogin; private ListAdapter loginListAdapter; private ArrayList<LoginDetails> loginArrayList; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login_listview); loginList = (ListView) findViewById(R.id.loginlist); loginList.setOnItemClickListener(this); webLogin = (Button) findViewById(R.id.button3); webLogin.setOnClickListener(this); loginArrayList = new ArrayList<LoginDetails>(); loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); loginList.setAdapter(loginListAdapter); } @Override public void onClick (View v) { Intent webLoginIntent = new Intent (this, LoginPlusActivity.class); startActivity(webLoginIntent); } public List<String> populateList () { List<String> webNameList = new ArrayList<String>(); dataStore openHelperClass = new dataStore (this); SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase(); Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null); startManagingCursor(cursor); while (cursor.moveToNext()) { String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE)); String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS)); String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME)); String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD)); String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES)); LoginDetails lpDetails = new LoginDetails(); lpDetails.setsName(sName); lpDetails.setwUrl(wUrl); lpDetails.setuName(uName); lpDetails.setpWord(pWord); lpDetails.setlNotes(lNotes); loginArrayList.add(lpDetails); webNameList.add(sName); } sqliteDatabase.close(); return webNameList; } @Override protected void onResume() { super.onResume(); loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, populateList()); loginList.setAdapter(loginListAdapter); } @Override public void onItemClick(AdapterView<?> arg0 , View arg1, int arg2, long arg3) { Toast.makeText(getApplicationContext(), "Selected ID :" + arg2, Toast.LENGTH_SHORT).show(); Intent updateDeleteLoginInfo = new Intent (this, UpdateDeleteLoginList.class); LoginDetails clickedObject = loginArrayList.get(arg2); Bundle loginBundle = new Bundle(); loginBundle.putString("clickedWebSite",clickedObject.getsName()); loginBundle.putString("clickedWebAddress",clickedObject.getwUrl()); loginBundle.putString("clickedUserName",clickedObject.getuName()); loginBundle.putString("clickedPassWord",clickedObject.getpWord()); loginBundle.putString("clickedNotes",clickedObject.getlNotes()); updateDeleteLoginInfo.putExtras(loginBundle); startActivityForResult(updateDeleteLoginInfo, 0); } } 
+7
source share
7 answers

This is exactly what works great for Loader . I suggest you create a SimpleCursorAdapter to bind the database to the user interface ( ListView in this case), a ContentProvider to interact with the database and CursorLoader to monitor the database to make changes and update the interface if necessary. Loader will process all database changes and update your ListView by simply updating your adapter. It seems like a lot of work ahead, but incredibly powerful after setting up and will work through the entire Android life cycle.

These tutorials should be helpful:

+5
source

Edit

 private ArrayList<LoginDetails> loginArrayList = new ArrayList<LoginDetails>();; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login_listview); loginList = (ListView) findViewById(R.id.loginlist); loginList.setOnItemClickListener(this); webLogin = (Button) findViewById(R.id.button3); webLogin.setOnClickListener(this); loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,loginArrayList ); loginList.setAdapter(loginListAdapter); populateList(); } @Override public void onClick (View v) { Intent webLoginIntent = new Intent (this, LoginPlusActivity.class); startActivity(webLoginIntent); } public void populateList () { loginListAdapter.clear(); loginArrayList.clear(); dataStore openHelperClass = new dataStore (this); SQLiteDatabase sqliteDatabase = openHelperClass.getReadableDatabase(); Cursor cursor = sqliteDatabase.query(dataStore.TABLE_NAME_INFOTABLE, null, null, null, null, null, dataStore.COLUMN_NAME_SITE, null); startManagingCursor(cursor); while (cursor.moveToNext()) { String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE)); String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS)); String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME)); String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD)); String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES)); LoginDetails lpDetails = new LoginDetails(); lpDetails.setsName(sName); lpDetails.setwUrl(wUrl); lpDetails.setuName(uName); lpDetails.setpWord(pWord); lpDetails.setlNotes(lNotes); loginArrayList.add(lpDetails); webNameList.add(sName); } loginListAdapter.notifyDatasetChanged(); sqliteDatabase.close(); } 

You lose the link to your list, why your list is not updated ...

Make this modification in your code. 1. Initialize your ArrayList when it is declared (globally).

 ArrayList loginArrayList = new ArrayList<LoginDetails>(); 
  • Directly set the list of assignments for the adapter (onCreate)

    loginListAdapter = new ArrayAdapter (this, android.R.layout.simple_list_item_1, loginArrayList);

  • calling populateList() in onCreate() .

  • In populateList() instead of adding data to a new list, add the existing list associated with your adapter loginArrayList

if your list is a completely new call to adapter.clear() and loginArrayList.clear() in populateList() before adding data to loginArrayList . After adding data to the call to loginArrayList adapter.notifyDataSetChanged()

This should work ...

+5
source

My recommendation.

  • Do not use a loop to load a list. If it is a simple list with all the lines. Try using the SimpleCursorAdapter and make your application faster and shorter.
  • After you update the database, you make a query in the database to get Cursor and Adapter . swapCursor(newCursor) . This will update your list while maintaining the scroll position.
0
source

If you manually create backup adapter data (in this case you use the ArrayAdapter, which is quite acceptable in many cases), then when changing the database you need to query the database, recreate the data set, change the base data set of your adapter and tell the list that changed data set.

A way to achieve this goal may be to broadcast an intention that allows your activity to know how to complete the above steps (by catching this intention with BroadcastReceiver).

0
source

Here is my sample code for editing each row, as well as the list database. Hope this helps you.

First create the adapter name "ListAdapterItem.java"

  import java.util.ArrayList; import java.util.HashMap; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.RelativeLayout; import android.widget.TextView; public class ListAdapterItem extends BaseAdapter { private ArrayList<HashMap<String, Object>> list; private Context context; private RelativeLayout ll; // used to keep selected position in ListView private int selectedPos = -1; // init value for not-selected private TextView label,label_id; String name,id; public ListAdapterItem (Context context,ArrayList<HashMap<String, Object>> list) { this.list = list; this.context = context; } public void setSelectedPosition(int pos) { selectedPos = pos; // inform the view of this change notifyDataSetChanged(); } public int getSelectedPosition() { return selectedPos; } public View getView(int position, View convertView, ViewGroup parent) { ll = (RelativeLayout) LayoutInflater.from(this.context).inflate(R.layout.data_list_item, null); // get text view label = (TextView) ll.findViewById(R.id.txtview_country_name); label_id=(TextView) ll.findViewById(R.id.txtview_id); id=list.get(position).get("Id").toString(); name = list.get(position).get("Name").toString(); label.setText(name); label_id.setText(id); return ll; } public int getCount() { return this.list.size(); } public Object getItem(int position) { return position; } public long getItemId(int position) { return position; } } 

And here is my data_list_item

  <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="fill_parent" android:orientation="vertical" android:padding="5dp"> <TextView android:id="@+id/txtview_id" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_margin="8dp" android:layout_marginRight="2dp" android:textColor="@android:color/black" android:textSize="22dp" android:visibility="invisible"/> <TextView android:id="@+id/txtview_country_name" android:layout_width="wrap_content" android:layout_height="fill_parent" android:layout_margin="8dp" android:layout_marginRight="2dp" android:textColor="@android:color/black" android:textSize="22dp" /> </RelativeLayout> 

And the main class is "Main.java"

  public class Main extends Activity implements OnClickListener { String name; SQLiteDatabase db; Cursor cursor; private ProgressDialog progressDialog; public ListAdapterItem list_adapter; private ArrayList<HashMap<String, Object>> lst_data; private HashMap<String, Object> hm; private ListView listview; private String list_id; private int counter_id,selectedPosition; private View selectedView; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); lst_data = new ArrayList<HashMap<String, Object>>(); listview = (ListView) findViewById(R.id.list); new FetchDB().execute(); } private class FetchDB extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> { protected void onPreExecute() { progressDialog = ProgressDialog.show(Main.this,"Fetching Data", "Loading,Please wait...", true); } protected ArrayList<HashMap<String, Object>> doInBackground(String... lstStrings)throws IllegalArgumentException { try { db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null); cursor = db.rawQuery("SELECT * FROM person WHERE Id <> ''",null); if (cursor != null && cursor.getCount() > 0) { if (cursor.moveToFirst()) { do { hm = new HashMap<String, Object>(); hm.put("Id",cursor.getInt(cursor.getColumnIndex("Id"))); hm.put("Name", cursor.getString(cursor.getColumnIndex("Name"))); lst_data.add(hm); } while (cursor.moveToNext()); }// end of cursor.moveToFirst() cursor.close(); } } catch (Exception e) { e.getMessage(); } db.close();// database close return lst_data; }// end of doInbackgournd @Override protected void onPostExecute(ArrayList<HashMap<String, Object>> result) { progressDialog.dismiss(); list_adapter = new ListAdapterItem(Main.this,result); listview.setAdapter(list_adapter); listview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { list_adapter.setSelectedPosition(arg2); selectedPosition = arg2; selectedView = arg1; list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString(); } }); } }// end of FetchDBTask private class SaveTask extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> { @Override protected void onPreExecute() { progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading,Please wait...", true); } protected ArrayList<HashMap<String, Object>> doInBackground(String... arg0)throws IllegalArgumentException { counter_id++; name = editext_name.getText().toString(); hm = new HashMap<String, Object>(); hm.put("Id",counter_id); hm.put("Name",name); lst_data.add(hm); saveDB(); return lst_data; }// end of doInbackgournd protected void onPostExecute(ArrayList<HashMap<String, Object>> result) { progressDialog.dismiss(); list_adapter = new ListAdapterItem(Main.this,result); listview.setAdapter(list_adapter); listview.setOnItemClickListener(new OnItemClickListener() { public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { list_adapter.setSelectedPosition(arg2); selectedPosition = arg2; selectedView = arg1; list_id=((TextView) selectedView.findViewById(R.id.txtview_id)).getText().toString(); } }); } }// end of saveTask public void saveDB(){ String sql; db = openOrCreateDatabase("MyDB", MODE_PRIVATE, null); // create table if not e exist db.execSQL("CREATE TABLE IF NOT EXISTS person(Name VARCHAR ,Id INT(3));"); sql = "SELECT * FROM person WHERE Id="+list_id; //selected or click row in list item Cursor cursor = db.rawQuery(sql, null); if (cursor.moveToFirst()) { String sqlUpdate = "UPDATE person SET Name=? WHERE Id="+db_id; db.execSQL(sqlUpdate, new Object[] {db_name}); cursor.close(); db.close();// database close } else {// empty insert String sqlInsert = "INSERT INTO person VALUES (?,"+null+")"; db.execSQL(sqlInsert, new Object[] {db_name,db_address,db_phone,db_email,db_license,db_comments,db_company,db_policy,db_phone_insurance,vehc_year,vehc_make,vehc_model,vehc_license,vehc_vinnum,vehc_color,db_position }); cursor.close(); db.close();// database close } } //Edit by row private class EditData extends AsyncTask<String, Void,ArrayList<HashMap<String, Object>>> { protected void onPreExecute() { progressDialog = ProgressDialog.show(Main.this,"Saving Data", "Loading Please wait...", true); } protected ArrayList<HashMap<String, Object>> doInBackground(String... id)throws IllegalArgumentException { name = editext_name.getText().toString(); hm = new HashMap<String, Object>(); hm.put("Id",counter_id); hm.put("Name",name); lst_data.set(selectedPosition, hm); //specific row update list_id=Integer.parseInt(edit_counter); saveDB(); return lst_data; }// end of doInbackgournd protected void onPostExecute(ArrayList<HashMap<String, Object>> result) { progressDialog.dismiss(); list_adapter = new ListAdapterItem(Main.this,result); listview.setAdapter(list_adapter); } } } 

And main_layout.xml

  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:background="@android:color/transparent" android:cacheColorHint="#00000000" android:dividerHeight="2dp" android:paddingTop="8dp" android:transcriptMode="normal" /> </LinearLayout> 

Indicate your identifier for each list in the list, hoping this answer to your question

0
source

I think in your populate () method, before the while block, you should call loginListAdapter.notifyDataSetChanged () and loginListAdapter.clear (); This will clear the adapter and pay attention to the new data list.

The block will look like this:

  loginListAdapter.notifyDataSetChanged(); loginListAdapter.clear(); while (cursor.moveToNext()) { String sName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_SITE)); String wUrl = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_ADDRESS)); String uName = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_USERNAME)); String pWord = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_PASSWORD)); String lNotes = cursor.getString(cursor.getColumnIndex(dataStore.COLUMN_NAME_NOTES)); LoginDetails lpDetails = new LoginDetails(); lpDetails.setsName(sName); lpDetails.setwUrl(wUrl); lpDetails.setuName(uName); lpDetails.setpWord(pWord); lpDetails.setlNotes(lNotes); loginArrayList.add(lpDetails); webNameList.add(sName); } 

I just edited because the order you call notification and clear is incorrect. A clear should happen after notification, this is what I got from my experience if the adapter did not redraw the list.

0
source

Try this code

in the add variable public area: List<String> arrayList = new ArrayList<String>();

and in onCreate () add this:

  arrayList = populateList(); 

// then add a variable to an adapter like this

 loginListAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arrayList ); 

in onResume () this code:

 @Override protected void onResume() { super.onResume(); loginArrayList.clear(); arrayList.clear(); arrayList = populateList(); loginListAdapter.notifyDataSetChanged() } 

Let us know if you have solved it.

0
source

All Articles