首先,我想就这个问题道歉,因为我知道这里有很多相似的问题,但没有一个答案可以解决我的问题。
正如问题的标题所示,当SQLiteDatabase中的数据发生变化时,我需要用新项填充ListView。
更具体......
我有一项活动,可以在 ListView 中显示联系人。在屏幕的底部,我有一个添加联系人的按钮(A 对话框弹出名称,电话号码等字段......)。
单击列表中的项目时,将打开另一个对话框。在该对话框中,有3个按钮用于SendSMS(到选定的联系人),编辑和删除联系人。
当我填写表格以添加新联系人或点击删除按钮时,我希望ListView刷新。
它没有发生。为了查看更新后的列表,我需要导航回来,然后再次启动“联系人”活动。
以下是代码:
活动:
public class ContactsActivity extends Activity {
private MyUtilities myUtilities;
private MyDatabaseHelper mdbh;
private AdapterContactListView contactsAdapter;
private ListView contactsListView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts);
mdbh = new MyDatabaseHelper(this);
myUtilities = new MyUtilities(this);
contactsAdapter = new AdapterContactListView(this,mdbh);
contactsListView = (ListView)findViewById(R.id.contactActivityLV);
contactsListView.setAdapter(contactsAdapter);
contactsAdapter.notifyDataSetChanged();
contactsListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// TODO Auto-generated method stub
TextView phoneNumberTV = (TextView)view.findViewById(R.id.contactElementNumberTV);
String phoneNumber = phoneNumberTV.getText().toString();
Contact contact = mdbh.getContactFromPhoneNumber(phoneNumber);
Dialog d = myUtilities.createSelectedContactOptionsDialog(contact);
d.show();
contactsAdapter.updateAdapter(mdbh.getAllContacts());
}
});
public void addContact(View view) {
Dialog d = myUtilities.createAddContactDialog();
d.show();
contactsAdapter.updateAdapter(mdbh.getAllContacts());
}
}
The Adater:
private List<Contact> allContacts;
private int numberOfContacts;
private MyDatabaseHelper mdbh;
private Context context;
public AdapterContactListView(Context c, MyDatabaseHelper m) {
super();
context = c;
mdbh = m;
allContacts = mdbh.getAllContacts();
numberOfContacts = allContacts.size();
}
public void updateAdapter(List<Contact> cs) {
allContacts = cs;
numberOfContacts = allContacts.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
View view = convertView;
if (view == null) {
LayoutInflater li = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.contact_element, null);
}
String fullName = allContacts.get(position).getFirstName();
fullName = fullName.concat(" ");
fullName = fullName.concat(allContacts.get(position).getLastName());
TextView contactName = (TextView)view.findViewById(R.id.contactElementNameTV);
TextView phoneNumber = (TextView)view.findViewById(R.id.contactElementNumberTV);
contactName.setText(fullName);
phoneNumber.setText(allContacts.get(position).getPhoneNumber());
return view;
}
对话框的工作是对数据库进行操作(更新,添加,删除)。
我尝试将notifyDataSetChanged()
放在updateAdapter()
之后和updateAdapter()
方法本身,但这些都不起作用。
有一件事我认为我可能会失踪:
定义notifyDataSetChanged()
表示通知附属观察员。我没有附加观察员,但在我读过的所有答案中,没有人提到关于附加观察者的任何事情。如果你认为这是问题,请告诉我如何做到这一点。
有人可以解释一下这个问题。
提前致谢。
答案 0 :(得分:0)
要刷新列表视图,您可以从名为notifydatasetchanged的列表中调用方法,但只有当您在contactsalllist中获取联系人时才能使用该方法。所以你需要做的是首先在你的arraylist中获取新数据,然后在listview上调用notifydataset。
除此之外,如果您使用的是Contacts数据库,我建议您使用simplecursoradapter而不是使用baseadapter,但它完全取决于您。无论如何我也为此添加了代码。如果它对你有帮助,请告诉我。
/**
*
* @author Syed Ahmed Hussain
*/
public class TestListActivity extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>, MultiChoiceModeListener {
NotificationsAdapter mNotificationAdapter;
ListView mNotificationsListView;
TextView mTxtNotificationsInfo;
Button mBtnCreateNotification;
public static final String TAG = "NotificationsList";
// ---------------------------------------------------------------------------
@Override
protected void onCreate(Bundle pSavedInstanceState) {
super.onCreate(pSavedInstanceState);
setContentView(R.layout.fragment_notifications);
initializeUIElements();
// registerForContextMenu(mNotificationsListView);
getSupportLoaderManager().initLoader(0, null, this);
mNotificationsListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
mNotificationsListView.setMultiChoiceModeListener(this);
}
// ---------------------------------------------------------------------------
/**
*
*/
private void initializeUIElements() {
mTxtNotificationsInfo = (TextView) findViewById(R.id.txtNotificationInfo);
mNotificationsListView = (ListView) findViewById(R.id.list_notifications);
mBtnCreateNotification = (Button) findViewById(R.id.btnAddNotification);
}
// ---------------------------------------------------------------------------
/**
*
*/
public void onCreateNewNotificationClick(View pV) {
Log.d(TAG, "onCreateNewNotificationClick");
Intent intent = new Intent(this, AddNewNotification.class);
startActivity(intent);
// setResult(0);
// finish();
}
// ---------------------------------------------------------------------------
@Override
public Loader<Cursor> onCreateLoader(int pId, Bundle pArgs) {
return new android.support.v4.content.CursorLoader(getApplicationContext(), NotificationsContentProvider.CONTENT_URI, null, null, null, null);
}
@Override
public void onLoadFinished(Loader<Cursor> pLoader, Cursor pData) {
if (pData == null || pData.getCount() == 0) {
Log.d("pData", "is null");
showTextView();
return;
}
mNotificationAdapter = new NotificationsAdapter(this, R.layout.item_notification, pData, new String[] { NotificationDatabaseHelper.COL_TITLE }, new int[] {R.id.txtNotificationTitle}, 0);
mNotificationsListView.setAdapter(mNotificationAdapter);
}
@Override
public void onLoaderReset(Loader<Cursor> pLoader) {
}
// ---------------------------------------------------------------------------
/**
* Hides the list view. shows the textview
*/
private void showTextView() {
mNotificationsListView.setVisibility(View.GONE);
mTxtNotificationsInfo.setVisibility(View.VISIBLE);
}
// ---------------------------------------------------------------------
// Multi-choice list item
@Override
public boolean onCreateActionMode(ActionMode pMode, Menu pMenu) {
// Inflate the menu for the CAB
MenuInflater inflater = pMode.getMenuInflater();
inflater.inflate(R.menu.menu_list_item, pMenu);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode pMode, Menu pMenu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode pMode, MenuItem pItem) {
switch (pItem.getItemId()) {
case 1:
Toast.makeText(getApplicationContext(), pItem.getTitle(), Toast.LENGTH_SHORT).show();
pMode.finish();
break;
case 2:
Toast.makeText(getApplicationContext(), pItem.getTitle(), Toast.LENGTH_SHORT).show();
pMode.finish();
break;
default:
break;
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode pMode) {
}
@Override
public void onItemCheckedStateChanged(ActionMode pMode, int pPosition, long pId, boolean pChecked) {
}
// --------------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.actionbar_menu_items, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
}
**
**
/**
*
* @author Syed Ahmed Hussain
*/
public class NotificationsAdapter extends SimpleCursorAdapter {
private LayoutInflater mLayoutInflater;
private Context mContext;
private int mLayout;
public NotificationsAdapter(Context pContext, int pLayout, Cursor pC, String[] pFrom, int[] pTo, int pFlags) {
super(pContext, pLayout, pC, pFrom, pTo, pFlags);
mLayout = pLayout;
mContext = pContext;
mLayoutInflater = LayoutInflater.from(mContext);
}
@Override
public View newView(Context pContext, Cursor pCursor, ViewGroup pParent) {
return mLayoutInflater.inflate(mLayout, null);
}
}
要在记录发生更改时更新它,请执行notifydatasetchange或获取刷新光标以获取所有值。回想一下返回数据集/光标的方法。