刷新当前片段(ListView数据)保留在同一活动中

调用一个ActivityFragment ,我显示一个ListView有两个Buttons 。 当我点击一个menu_item (即显示在线),我正在更新数据,所以ListView 。 现在我需要反映更新的数据。 我点击“在线显示”后,如何刷新Fragment 。 到目前为止,我已经使用了以下代码:

 Intent intent = getIntent(); Intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); finish(); startActivity(intent); 

但是这会重新启动整个Activity 。 我只需要刷新当前的Fragment

在这里输入图像说明在这里输入图像说明

编辑:代码已添加

活动类别

  public class ContactListActivity extends ActionBarActivity { ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); final ActionBar actionBar = getActionBar(); MenuButtonUtil.enableMenuButton(this); FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); MyContactsFragment contactListFragment = new MyContactsFragment (); fragmentTransaction.replace(android.R.id.content, contactListFragment); fragmentTransaction.commit(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.show_online) { ContentValues values = new ContentValues(); String where = "((" + ContactsContentProvider.PHONE_ID + " NOTNULL) AND ((" + ContactsContentProvider.PHONE_ID+ " = 17486 )OR (" + ContactsContentProvider.PHONE_ID+ " = 17494 )))"; values.put(ContactsContentProvider.STATUS, true); this.getContentResolver().update(ContactsContentProvider.CONTENT_URI, values, where, null); listView = (ListView) this.findViewById(android.R.id.list); ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged(); return true; } return super.onOptionsItemSelected(item); } } 

分段

 public class MyContactsFragment extends ListFragment{ Button allContactsBtn; Button neeoContactsBtn; ListView listView; CustomAdapterForAllContacts adapterForAllContacts; CustomAdapterForNeeoContacts adapterForNeeoContacts; @Override public void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); final ActionBar actionBar = getActivity().getActionBar(); MenuButtonUtil.enableMenuButton(getActivity()); adapterForNeeoContacts = new CustomAdapterForNeeoContacts(); adapterForAllContacts = new CustomAdapterForAllContacts(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) { View view = inflater.inflate(R.layout.contactsfragment, container,false); allContactsBtn = (Button) view.findViewById(R.id.allContactsButton); neeoContactsBtn = (Button) view.findViewById(R.id.neeoContactsButton); listView = (ListView) view.findViewById(android.R.id.list); // ==================== Neeo Contacts ============================ neeoContactsBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listView.setAdapter(adapterForNeeoContacts); } }); // ====================== All Contacts ============================= allContactsBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { listView.setAdapter(adapterForAllContacts); } }); return view; } 

适配器

 private class CustomAdapterForAllContacts extends BaseAdapter { public CustomAdapterForAllContacts(){ } List<Contact> contactsList = getAllContacts(); @Override public int getCount() { // TODO Auto-generated method stub return contactsList.size(); } @Override public Contact getItem(int arg0) { // TODO Auto-generated method stub return contactsList.get(arg0); } @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } @Override public View getView(int position, View view, ViewGroup viewGroup) { if(view==null) { LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); view = inflater.inflate(R.layout.list_item, viewGroup,false); } TextView contName = (TextView)view.findViewById(R.id.nameText); TextView contNumber = (TextView)view.findViewById(R.id.numberText); ImageView image = (ImageView)view.findViewById(R.id.contact_image); Contact contact = contactsList.get(position); String status = contact.getStatus(); if(contact.getStatus().equals("1")){ image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online); }else{ image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline); } contName.setText(contact.getName()); contNumber.setText(contact.getPhoneNumber()); return view; } public Contact getContactPosition(int position) { return contactsList.get(position); } public List<Contact> getAllContacts(){ List<Contact> contactList = new ArrayList<Contact>(); String URL = "content://com.example.provider.Contacts/contacts"; Uri baseUri1 = Uri.parse(URL); String[] select = {ContactsContentProvider.PHONE_ID, ContactsContentProvider.STATUS}; String where = "((" + ContactsContentProvider.NEEO_USER + " NOTNULL) AND (" + ContactsContentProvider.NEEO_USER+ " = 1 )AND (" + ContactsContentProvider.STATUS+ " = 1 ))"; Cursor cursor = getActivity().getContentResolver().query(baseUri1, select, where, null, "pid"); for(cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) { Log.w("Filtered IDS",""+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID))+ ""+ cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); } Uri baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; String[] projection = new String[] { ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; String selection = "((" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " != ' ' ))"; String[] selectionArgs = null; String sortOrder = ContactsContract.CommonDataKinds.Phone._ID + " COLLATE LOCALIZED ASC"; Cursor mCursor= getActivity().getContentResolver().query(baseUri, projection, selection, selectionArgs, sortOrder); // Joinging Both Cursors CursorJoiner joiner = new CursorJoiner(cursor, new String[] {ContactsContentProvider.PHONE_ID} , mCursor, new String[] {ContactsContract.CommonDataKinds.Phone._ID}); for (CursorJoiner.Result joinerResult : joiner) { Contact cont = new Contact(); Log.e("Result", joinerResult.toString()); switch (joinerResult) { case LEFT: // handle case where a row in cursorA is unique break; case RIGHT: // handle case where a row in cursorB is unique cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); cont.setStatus("0"); contactList.add(cont); break; case BOTH: // handle case where a row with the same key is in both cursors cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); cont.setStatus(cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); contactList.add(cont); break; } } mCursor.close(); cursor.close(); return contactList; } } 

Solutions Collecting From Web of "刷新当前片段(ListView数据)保留在同一活动中"

你有多个选项来解决这个问题,取决于你如何实现你的ListViewAdapter

  1. 通过调用notifyDataSetChanged()
  2. 通过重置Adapter

使用notifyDataSetChanged()更新

这是最好的解决scheme,但是您需要修改Adapter使用的List以使其工作。 例如,如果你像这样使用ArrayAdapter

 String[] dataSource = new String[] { "A", "B", "C", ... }; ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, dataSource); 

正如你所看到的String[]是我们的Adapter的dataSource。 我们可以像这样修改数组,但这些更改不会立即反映在ListView

 dataSource[0] = "some new String value"; 

只有我们调用notifyDataSetChanged()ListView才会被更新:

 adapter.notifyDataSetChanged(); 

文档

public void notifyDataSetChanged()

通知附加的观察者,底层数据已经被更改,任何反映数据集的视图都应该刷新自己。

不要notifyDataSetChanged()notifyDataSetInvalidated()混淆,因为notifyDataSetInvalidated()做一些完全不同的事情,只会搞乱ListView

文档

public void notifyDataSetInvalidated()

通知所附的观察员,底层数据不再有效或可用。 一旦调用此适配器不再有效,不应报告进一步的数据集更改。


通过重置Adapter更新

这非常简单。 每次你设置一个新的AdapterListView都会自动更新。 如果由于某种原因你不能使用notifyDataSetChanged() ,那么你必须这样做。 每当你想更新你的ListView时,只需创build一个新的Adapter

 ArrayAdapter<String> adapter = new ArrayAdapter<String>(context, R.layout.example, newData); 

并使用setAdapter()将其设置为ListView

 listView.setAdapter(adapter); 

这将始终更新ListView但是这个解决scheme有一些问题。 首先,每当你用这种方式更新ListView时候,它会回滚到顶端,当频繁更新或ListView有很多内容的时候,这可能会非常烦人。


编辑:

代码中有几件事情不是非常理想的。 首先,您的Adapter不应该包含下载联系人的代码。 它只是不属于那里, Adapter的唯一责任应该是他从一个给定的数据源创buildViews 。 所以首先你应该把getAllContacts()方法移到Adapter之外。 我build议你为此创build静态帮助器方法,我冒昧地修改你的代码:

 public class ContactsHelper { public static List<Contact> getAllContacts(Context context) { List<Contact> contactList = new ArrayList<Contact>(); String URL = "content://com.example.provider.Contacts/contacts"; Uri baseUri1 = Uri.parse(URL); String[] select = {ContactsContentProvider.PHONE_ID, ContactsContentProvider.STATUS}; String where = "((" + ContactsContentProvider.NEEO_USER + " NOTNULL) AND (" + ContactsContentProvider.NEEO_USER + " = 1 )AND (" + ContactsContentProvider.STATUS + " = 1 ))"; Cursor cursor = context.getContentResolver().query(baseUri1, select, where, null, "pid"); for (cursor.moveToFirst(); cursor.moveToNext(); cursor.isAfterLast()) { Log.w("Filtered IDS", "" + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.PHONE_ID)) + "" + cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); } Uri baseUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI; String[] projection = new String[]{ ContactsContract.CommonDataKinds.Phone._ID, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; String selection = "((" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " NOTNULL) AND (" + ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " != ' ' ))"; String[] selectionArgs = null; String sortOrder = ContactsContract.CommonDataKinds.Phone._ID + " COLLATE LOCALIZED ASC"; Cursor mCursor = context.getContentResolver().query(baseUri, projection, selection, selectionArgs, sortOrder); // Joinging Both Cursors CursorJoiner joiner = new CursorJoiner(cursor, new String[]{ContactsContentProvider.PHONE_ID}, mCursor, new String[]{ContactsContract.CommonDataKinds.Phone._ID}); for (CursorJoiner.Result joinerResult : joiner) { Contact cont = new Contact(); Log.e("Result", joinerResult.toString()); switch (joinerResult) { case LEFT: // handle case where a row in cursorA is unique break; case RIGHT: // handle case where a row in cursorB is unique cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); cont.setStatus("0"); contactList.add(cont); break; case BOTH: // handle case where a row with the same key is in both cursors cont.setID(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID))); cont.setName(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))); cont.setPhoneNumber(mCursor.getString(mCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))); cont.setStatus(cursor.getString(cursor.getColumnIndex(ContactsContentProvider.STATUS))); contactList.add(cont); break; } } mCursor.close(); cursor.close(); return contactList; } } 

有了这个代码,你可以得到像这样的所有联系人:

 List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); 

在此之后,我们需要修改您的Adapter以便notifyDateSetChanged()将工作:

 private class CustomAdapterForAllContacts extends BaseAdapter { private final List<Contact> contactsList; private final LayoutInflater inflater; public CustomAdapterForAllContacts(Context context, List<Contact> contacts) { this.inflater = LayoutInflater.from(context); this.contactsList = contacts; } @Override public int getCount() { return contactsList.size(); } @Override public Contact getItem(int position) { return contactsList.get(position); } @Override public long getItemId(int position) { return position; } // We expose the List so we can modify it from outside public List<Contact> contacts() { return this.contactsList; } private class SimpleViewHolder { private final SparseArray<View> viewArray = new SparseArray<View>(); private final View convertView; public SimpleViewHolder(View convertView) { this.convertView = convertView; } public View get(int id) { View view = this.viewArray.get(id, null); if(view == null) { view = this.convertView.findViewById(id); this.viewArray.put(id, view); } return view; } } @Override public View getView(int position, View convertView, ViewGroup viewGroup) { // By implementing the view holder pattern you only need to perform // findViewById() once. This will improve the performance of `ListView` // and reduce lag. SimpleViewHolder viewHolder; if (convertView == null) { convertView = this.inflater.inflate(R.layout.list_item, viewGroup, false); viewHolder = new SimpleViewHolder(convertView); convertView.setTag(viewHolder); } viewHolder = (SimpleViewHolder) convertView.getTag(); TextView contName = (TextView) viewHolder.get(R.id.nameText); TextView contNumber = (TextView) viewHolder.get(R.id.numberText); ImageView image = (ImageView) viewHolder.get(R.id.contact_image); Contact contact = getItem(position); String status = contact.getStatus(); if (contact.getStatus().equals("1")) { image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_online); } else { image.setBackgroundResource(com.example.mycontentprovider.R.drawable.person_empty_offline); } contName.setText(contact.getName()); contNumber.setText(contact.getPhoneNumber()); return view; } } 

我在这个Adapter改变了多个东西。 首先, Contacts List现在是最终的,我添加了一个方法contacts()来公开List以便我们可以从外部修改Adapter的数据。 我也实现了查看持有人模式,让您的ListView滚动更快,更顺畅!

我希望我没有忘记任何东西,但这应该是你所需要的一切改变。 你可以像这样使用新的Adapter

 List<Contact> contacts = ContactsHelper.getAllContacts(getActivity()); CustomAdapterForAllContacts adapter = new CustomAdapterForAllContacts(getActivity(), contacts); listView.setAdapter(adapter); 

如果你想稍后更新ListView ,你需要像这样修改AdapterList

 List<Contact> newData = ContactsHelper.getAllContacts(getActivity()); adapter.contacts().clear(); adapter.contacts().addAll(newData); adapter.notifyDataSetChanged(); 

我希望我能帮助你,如果你有任何问题,请随时询问!

如果你在一个片段内,那么你可以做

 // code for fetching the data // ... // ... ((BaseAdapter) yourlistview.getAdapter()).notifyDataSetChanged();