Android ListView刷新

我有一个Listview ,它从sqlite数据库中提取和显示数据。 数据库的第一列中的数据显示在ListView ,点击后, Activity开始显示与第一列关联的列的其余部分。 在编辑数据时,需要更新ListView以反映这一点,但是除非应用程序重新启动,否则不会显示更新。

我已经尝试在我的onResume()方法中调用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所擅长的。 我build议你创build一个SimpleCursorAdapter来绑定数据库到UI(在这种情况下是ListView ),一个ContentProvider与数据库接口,一个CursorLoader监视数据库的变化,并在必要时更新UI。 Loader将处理所有数据库更改,并通过更新您的适配器来更新您的ListView 。 看起来好像有很多工作要做,但是一旦configuration完成,它将非常强大,并且可以贯穿整个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 = new ArrayAdapter(this,android.R.layout.simple_list_item_1,loginArrayList);

  2. 调用onCreate() populateList() onCreate()

  3. 在您的populateList()而不是将数据添加到新列表中添加到与您的适配器即loginArrayList关联的现有列表

如果在将数据添加到loginArrayList之前,您的列表完全是新的,请调用adapter.clear()loginArrayList.clear() 。 在将数据添加到loginArrayList调用adapter.notifyDataSetChanged()

这应该工作…

我的推荐。

  1. 不要做一个循环来加载你的列表。 如果它是一个包含所有string的简单列表。 尝试使用SimpleCursorAdapter ,并将使您的应用程序更快,更短的代码。
  2. 一旦你更新了数据库,那么你所做的就是查询数据库来获取Cursor ,并使用AdapterswapCursor(newCursor) 。 这将更新您的列表,同时保持滚动位置。

如果您正在手动创build适配器的后备数据(在这种情况下,您正在使用ArrayAdapter – 在许多情况下这是完全可以接受的),那么当数据库发生变化时,您需要重新查询数据库,重新创build数据集,更改您的适配器的后备数据集,并告诉列表数据集已更改。

实现这一目标的一种方法可能是广播一个意图,让您的活动知道执行上述步骤(通过捕获该意图与BroadcastReceiver)。

这里是我的示例代码来编辑每行以及listview的数据库,我希望它会帮助你

首先创build一个适配器名称“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> 

在listview中指定你的id每个listrow希望这个回答你的问题

我认为,在你的populate()方法之前,你应该调用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); } 

我只是编辑,因为你所说的通知和清除命令是不正确的。 明确必须发生通知后,正是我从我的经验,除非适配器不会重画列表。

试试这个代码

在公共区域添加variables: List<String> arrayList = new ArrayList<String>();

并在onCreate()添加这个:

  arrayList = populateList(); 

//然后像这样在适配器中添加variables

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

在onResume()这个代码中:

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

让我们知道如果你解决了它。