Actualizar fragmento actual (datos ListView) que permanece en la misma actividad

Llamando a un Fragment de una Activity , estoy mostrando un ListView con dos Buttons . Cuando hago clic en un menu_item (es decir, mostrar en línea), estoy actualizando los datos y por lo tanto el ListView . Ahora necesito reflejar los datos actualizados. ¿Cómo puedo actualizar el Fragment después de hacer clic en Mostrar en línea. Hasta ahora, he utilizado el código siguiente:

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

Pero esto reiniciará toda la Activity . Sólo necesito actualizar el Fragment actual.

Introduzca aquí la descripción de la imagenIntroduzca aquí la descripción de la imagen

Editado: Código añadido

CLASE DE ACTIVIDAD

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

Fragmento

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

Adaptador :

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

Tiene varias opciones para solucionar esto dependiendo de cómo exactamente implementó su ListView y Adapter .

  1. Llamando a notifyDataSetChanged()
  2. Al restablecer el Adapter

Actualizando con notifyDataSetChanged ()

Esta es la mejor solución que hay, pero es necesario modificar la List el Adapter está usando para que esto funcione. Por ejemplo, si utiliza un ArrayAdapter como este:

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

Como se puede ver el String[] es el dataSource para nuestro Adapter . Podemos modificar la matriz de este modo, pero esos cambios no se reflejarán inmediatamente en ListView :

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

Sólo una vez que llamemos a notifyDataSetChanged() se actualizará ListView :

 adapter.notifyDataSetChanged(); 

De la documentación :

Public void notifyDataSetChanged ()

Notifica a los observadores adjuntos que los datos subyacentes han sido cambiados y que cualquier vista que refleja el conjunto de datos debe actualizarse.

Pero NO confundir notifyDataSetChanged() con notifyDataSetInvalidated() , porque notifyDataSetInvalidated() hace algo completamente diferente y sólo desordenar su ListView .

De la documentación :

Public void notifyDataSetInvalidated ()

Notifica a los observadores adjuntos que los datos subyacentes ya no son válidos o no están disponibles. Una vez invocado este adaptador ya no es válido y no debe informar más cambios de conjunto de datos.


Actualización mediante el restablecimiento del Adapter

Esto es bastante sencillo. Cada vez que establezca un nuevo Adapter el ListView se actualizará. Si no puede usar notifyDataSetChanged() por alguna razón entonces usted tiene que hacerlo de esta manera. Simplemente cree un nuevo Adapter cada vez que desee actualizar su ListView :

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

Y use setAdapter() para establecerlo en ListView :

 listView.setAdapter(adapter); 

Esto siempre actualizará el ListView pero hay algunos problemas con esta solución. Primero y ante todo cada vez que actualizas el ListView esta manera se desplazaría de nuevo a la parte superior que puede ser bastante molesto cuando hay actualizaciones frecuentes o cuando hay un montón de contenido en el ListView .


EDITAR:

Hay algunas cosas en su código que no son muy óptimas. En primer lugar, su Adapter no debe contener el código para descargar los contactos. Simplemente no pertenece allí, la única responsabilidad de un Adapter debe ser que crea Views desde una fuente de datos determinada. Así que primero debes mover el método getAllContacts() fuera del Adapter . Le sugiero que crear un método de ayuda estática para esto, tomé la libertad de modificar su código en consecuencia:

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

Con este código puede obtener todos los contactos como este:

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

Después de esto debemos modificar su Adapter para que notifyDateSetChanged() funcione:

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

He cambiado varias cosas en este Adapter . En primer lugar la List de Contacts es ahora final y agregué un método contacts() para exponer la List para que podamos modificar los datos en el Adapter desde el exterior. ¡También implementé el patrón del sostenedor de la visión así que su ListView desplaza más rápidamente y más liso!

Espero no haber olvidado nada, pero esto debe ser todos los cambios que necesita. Puede utilizar el nuevo Adapter esta manera:

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

Si desea actualizar el ListView posteriormente, deberá modificar la List dentro del Adapter siguiente manera:

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

¡Espero poder ayudarle y si usted tiene alguna otra pregunta por favor no dude en preguntar!

Si estás dentro de un Fragmento, entonces puedes hacerlo

 // code for fetching the data // ... // ... ((BaseAdapter) yourlistview.getAdapter()).notifyDataSetChanged(); 
  • Agregar vistas de forma programática en un diseño (lineal) (que está dentro de un ScrollView)
  • Cómo implementar simple como botón en listview de cada elemento
  • Cómo hacer un fragmento desplazable con un ListView
  • Botón de acción flotante Cambios de anclaje en la creación de vistas
  • YouTubePlayerFragment en ListView con AppCompatActivity Error
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.