Android ListView обновить

У меня есть Listview который тянет и отображает данные из базы данных sqlite. Данные в первом столбце БД отображаются в ListView и при нажатии, Activity начинает показывать остальную часть столбца, связанного с первым столбцом. Когда данные редактируются, ListView необходимо обновить, чтобы отразить это, но он не показывает обновления, если приложение не перезапущено.

Я попытался вызвать, notifyDataSetChanged() и startActivityForResult() в моем onResume() но это не сработало. Какой метод следует использовать для выполнения обновления ListView в моем текущем коде?

Я понимаю, что SimpleCursorAdapter можно использовать, и я попытался реализовать этот код без успеха. Я новичок и нуждаюсь в реальном коде, чтобы понять, что нужно сделать.

 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); } } 

Solutions Collecting From Web of "Android ListView обновить"

Это то, для чего отлично подходит Loader . Я предлагаю вам создать SimpleCursorAdapter для привязки БД к пользовательскому интерфейсу ( ListView в этом случае), ContentProvider для взаимодействия с БД и CursorLoader для мониторинга БД для изменений и обновления интерфейса при необходимости. Loader будет обрабатывать все изменения базы данных и обновлять ListView , просто обновляя ваш адаптер. Похоже, что много работы впереди, но невероятно мощно настроено и будет работать через весь жизненный цикл Android.

Эти учебные пособия должны быть полезными:

редактировать

 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(); } 

Вы теряете ссылку на свой список, почему ваш список не обновляется …

Сделайте это изменение в своем коде. 1. Инициализируйте свой ArrayList, когда он объявлен (глобально).

 ArrayList loginArrayList = new ArrayList<LoginDetails>(); 
  1. Непосредственно задайте список назначений для адаптера (onCreate)

    LoginListAdapter = новый ArrayAdapter (это, android.R.layout.simple_list_item_1, loginArrayList);

  2. onCreate() в onCreate() .

  3. В вашем populateList() вместо добавления данных в новый список добавьте существующий список, связанный с вашим адаптером, т.е. loginArrayList

Если ваш список является полностью новым вызовом adapter.clear() и loginArrayList.clear() в loginArrayList.clear() populateList() перед добавлением данных в loginArrayList . После добавления данных в loginArrayList call adapter.notifyDataSetChanged()

Это должно работать …

Мое одобрение.

  1. Не выполняйте цикл, чтобы загрузить список. Если это простой список со всеми строками. Попробуйте использовать SimpleCursorAdapter и сделает ваше приложение более быстрым и коротким.
  2. После того, как вы обновите базу данных, то, что вы делаете, это запрос БД для получения Cursor и использования Adapter . swapCursor(newCursor) . Это обновит ваш список, сохранив положение прокрутки.

Если вы вручную создаете резервные данные адаптера (в этом случае вы используете ArrayAdapter, что вполне приемлемо во многих случаях), то при изменении базы данных вам необходимо запрашивать базу данных, воссоздать свой набор данных, изменить Резервный набор данных вашего адаптера, и сообщите списку, который изменил набор данных.

Способ достижения этого может заключаться в трансляции намерений, которые позволяют вашей деятельности знать, чтобы выполнить описанные выше шаги (поймав это намерение с помощью BroadcastReceiver).

Вот мой пример кода для редактирования каждой строки, а также базы данных списка. Надеюсь, это поможет вам

Сначала создайте имя адаптера "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; } } 

И вот мой 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> 

И основной класс «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); } } } 

И 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> 

Укажите свой идентификатор каждого списка в списке, надеясь, что этот ответ на ваш вопрос

Я думаю, что в вашем методе populate () перед блоком while вы должны вызвать loginListAdapter.notifyDataSetChanged () и loginListAdapter.clear (); Это позволит очистить адаптер и обратить внимание на новый список данных.

Блок будет выглядеть так:

  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); } 

Я только что отредактировал, потому что порядок, который вы называете уведомлением и ясным, неверен. Ясное должно произойти после уведомления, это то, что я получил от своего опыта, если адаптер не перерисовал список.

Попробуйте этот код

В публичной области добавить переменную: List<String> arrayList = new ArrayList<String>();

И в onCreate () добавьте это:

  arrayList = populateList(); 

// затем добавим переменную в адаптер, как это

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

In onResume () этот код:

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

Сообщите нам, если вы решили.