web-dev-qa-db-fra.com

Actualiser le fragment actuel (données de liste d'affichage) restant dans la même activité

En appelant une Fragment à partir d'une Activity, j'affiche une ListView avec deux Buttons. Lorsque je clique sur un menu_item (c’est-à-dire Show Online), je mets à jour les données et donc la ListView. Maintenant, je dois refléter les données mises à jour. Comment puis-je actualiser la Fragment après avoir cliqué sur Afficher en ligne? Jusqu'à présent, j'ai utilisé le code suivant: 

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

Mais cela va redémarrer toute la Activity. Je dois juste actualiser la Fragment actuelle. 

enter image description hereenter image description here

Edited: Code Added

CLASSE D'ACTIVITÉ

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

}

Fragment

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

Adaptateur :

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;
    }
}  
8
BST Kaal

Vous avez plusieurs options pour résoudre ce problème, en fonction de la manière dont vous avez implémenté votre ListView et Adapter.

  1. En appelant notifyDataSetChanged()
  2. En réinitialisant la Adapter

Mise à jour avec notifyDataSetChanged ()

C'est la meilleure solution qui existe, mais vous devez modifier la List utilisée par la Adapter pour que cela fonctionne. Par exemple, si vous utilisez une ArrayAdapter comme ceci:

String[] dataSource = new String[] {
    "A", "B", "C", ...
};

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

Comme vous pouvez le constater, le String[] est la source de données pour notre Adapter. Nous pouvons modifier le tableau de cette manière, mais ces modifications ne seront pas immédiatement reflétées dans la ListView:

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

La ListView ne sera mise à jour que lorsque nous aurons appelé notifyDataSetChanged():

adapter.notifyDataSetChanged();

À partir de documentation :

public void notifyDataSetChanged ()

Notifie les observateurs attachés que les données sous-jacentes ont été modifiées. Et que toute vue reflétant le jeu de données doit s'actualiser.

Mais NE PAS confondre notifyDataSetChanged() avec notifyDataSetInvalidated(), car notifyDataSetInvalidated() fait quelque chose de complètement différent et gâcherait simplement votre ListView.

À partir de documentation :

public voich notifyDataSetInvalidated ()

Notifie les observateurs attachés que les données sous-jacentes ne sont plus Valides ou disponibles. Une fois appelé, cet adaptateur n'est plus valide et Ne doit plus signaler les modifications ultérieures apportées au fichier.


Mise à jour en réinitialisant la Adapter

C'est assez simple. Chaque fois que vous définissez une nouvelle Adapter, la ListView se mettra à jour. Si vous ne pouvez pas utiliser notifyDataSetChanged() pour une raison quelconque, vous devez le faire comme ceci. Créez simplement une nouvelle Adapter chaque fois que vous souhaitez mettre à jour votre ListView:

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

Et utilisez setAdapter() pour le régler sur ListView:

listView.setAdapter(adapter);

Ceci mettra toujours à jour la ListView mais il y a quelques problèmes avec cette solution. Avant toute chose, chaque fois que vous mettez à jour la ListView de cette façon, le défilement reviendrait au début, ce qui peut être assez gênant lorsqu'il y a de fréquentes mises à jour ou qu'il y a beaucoup de contenu dans la ListView.


EDIT:

Votre code contient quelques éléments qui ne sont pas tout à fait optimaux. Tout d’abord, votre Adapter ne doit pas contenir le code pour télécharger les contacts. Cela n’appartient pas à cela, la seule responsabilité d’un Adapter devrait être qu’il crée Views à partir d’une source de données donnée. Vous devez donc commencer par déplacer la méthode getAllContacts() en dehors de Adapter. Je vous suggère de créer une méthode d'assistance statique pour cela, j'ai pris la liberté de modifier votre code en conséquence:

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

Avec ce code, vous pouvez obtenir tous les contacts comme ceci:

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

Après cela, nous devons modifier votre Adapter pour que notifyDateSetChanged() fonctionne:

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

J'ai changé plusieurs choses dans cette Adapter. D'abord et avant tout, la List de Contacts est maintenant finale et j'ai ajouté une méthode contacts() pour exposer la List afin que nous puissions modifier les données de la Adapter de l'extérieur. J'ai également implémenté le modèle de détenteur de vue pour que votre ListView défile plus rapidement et plus facilement!

J'espère ne rien avoir oublié, mais cela devrait représenter tous les changements dont vous avez besoin. Vous pouvez utiliser la nouvelle Adapter comme ceci:

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

Si vous souhaitez mettre à jour la ListView ultérieurement, vous devez modifier la List dans la Adapter comme ceci:

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

J'espère pouvoir vous aider et si vous avez d'autres questions, n'hésitez pas à demander!

14
Xaver Kapeller

Si vous êtes à l'intérieur d'un fragment, alors vous pouvez faire

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