简体   繁体   中英

How do I manipulate listview so a specific phone number always appears at the top?

How can I make the phone number 3456781276 which is in my phone contacts appear at the very top of my listview , and then all other contacts below that as normal? I believe I pass that value into my custom adapter and into my getView() but not at all sure how to proceed. Can you help?

In my ListView I show all my phone contacts with the following code:

  class LoadContact extends AsyncTask<Void, Void, Void> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected Void doInBackground(Void... voids) {


//          we want to delete the old selectContacts from the listview when the Activity loads
//          because it may need to be updated and we want the user to see the updated listview,
//          like if the user adds new names and numbers to their phone contacts.
            selectPhoneContacts.clear();

//          we have this here to avoid cursor errors
            if (cursor != null) {
                cursor.moveToFirst();

            }


            try {

//                get a handle on the Content Resolver, so we can query the provider,
                cursor = getApplicationContext().getContentResolver()
//                the table to query
                 .query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                                null,
                                null,
                                null,
//               display in ascending order
                 ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " COLLATE LOCALIZED ASC");

//                get the column number of the Contact_ID column, make it an integer.
//                I think having it stored as a number makes for faster operations later on.
//                get the column number of the DISPLAY_NAME column
                int nameIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
//                 get the column number of the NUMBER column
                int phoneNumberofContactIdx = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);

                cursor.moveToFirst();

//              We make a new Hashset to hold all our contact_ids, including duplicates, if they come up
                Set<String> ids = new HashSet<>();

                do {

                    System.out.println("=====>in while");

//                        get a handle on the display name, which is a string
                    name = cursor.getString(nameIdx);

//                        get a handle on the phone number, which is a string
                    phoneNumberofContact = cursor.getString(phoneNumberofContactIdx);


                    //----------------------------------------------------------


                    // get a handle on the phone number of contact, which is a string. Loop through all the phone numbers
//                  if our Hashset doesn't already contain the phone number string,
//                    then add it to the hashset
                    if (!ids.contains(phoneNumberofContact)) {
                        ids.add(phoneNumberofContact);

                        System.out.println(" Name--->" + name);
                        System.out.println(" Phone number of contact--->" + phoneNumberofContact);

                                SelectPhoneContact selectContact = new SelectPhoneContact();

                                selectContact.setName(name);
                                selectContact.setPhone(phoneNumberofContact);
                                selectPhoneContacts.add(selectContact);
                    }

                } while (cursor.moveToNext());


            } catch (Exception e) {
                Toast.makeText(NewContact.this, "what the...", Toast.LENGTH_LONG).show();
                e.printStackTrace();
                //   cursor.close();
            } finally {

            }


    if (cursor != null) {
        cursor.close();

    }
    return null;
}


        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);

            adapter = new SelectPhoneContactAdapter(selectPhoneContacts, NewContact.this);

//                    we need to notify the listview that changes may have been made on
//                    the background thread, doInBackground, like adding or deleting contacts,
//                    and these changes need to be reflected visibly in the listview. It works
//                    in conjunction with selectContacts.clear()
            adapter.notifyDataSetChanged();

            listView.setAdapter(adapter);

            //this function measures the height of the listview, with all the contacts, and loads it to be that
            //size. We need to do this because there's a problem with a listview in a scrollview.
            justifyListViewHeightBasedOnChildren(listView);

        }
    }

My model, getters and setters, is like:

public class SelectPhoneContact {

    String phone;

    public String getPhone() {return phone;}

    public void setPhone(String phone) {
        this.phone = phone;
    }

    String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

And my custom adapter:

 public class SelectPhoneContactAdapter extends BaseAdapter {

    //define a list made out of SelectContacts and call it theContactsList
    public List<SelectPhoneContact> theContactsList;
    //define an array list made out of SelectContacts and call it arraylist
    private ArrayList<SelectPhoneContact> arraylist;
    Context _c;

    //define a ViewHolder to hold our name and number info, instead of constantly querying
    // findviewbyid. Makes the ListView run smoother
    ViewHolder v;

    public SelectPhoneContactAdapter(List<SelectPhoneContact> selectPhoneContacts, Context context) {
        theContactsList = selectPhoneContacts;
        _c = context;
        this.arraylist = new ArrayList<SelectPhoneContact>();
        this.arraylist.addAll(theContactsList);


        Collections.sort(this.arraylist, new Comparator<SelectPhoneContact>() {
                @Override
                public int compare(SelectPhoneContact t1, SelectPhoneContact t2) {
                    if(t2.getPhone().equals ("3456781276")) {   // put the phone number you want on top here
                        return 1;
                    } else {
                        return t1.getName().compareTo(t2.getName());
                    }
                }


            });

        }



    @Override
    public int getCount() {
        return arraylist.size();
    }

    @Override
    public Object getItem(int i) {
        return arraylist.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)

    static class ViewHolder {
        //        In each cell in the listview show the items you want to have
//        Having a ViewHolder caches our ids, instead of having to call and load each one again and again
        CheckBox checkbox;
        TextView title, phone, lookup;
//        CheckBox check;
    }

    @Override
    public View getView(int i, View convertView, ViewGroup viewGroup) {

        //we're naming our convertView as view
        View view = convertView;

        if (view == null) {

            //if there is nothing there (if it's null) inflate the layout for each row
            LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = li.inflate(R.layout.phone_inflate_listview, null);

            //or else use the view (what we can see in each row) that is already there
        } else {
            view = convertView;
        }

        v = new ViewHolder();

//      So, for example, title is cast to the name id, in phone_inflate_listview,
//        phone is cast to the id called no etc
        v.title = (TextView) view.findViewById(R.id.name);
//        v.check = (CheckBox) view.findViewById(R.id.check);
        v.phone = (TextView) view.findViewById(R.id.no);

//        store the holder with the view
        final SelectPhoneContact data = (SelectPhoneContact) arraylist.get(i);
        v.title.setText(data.getName());
        v.phone.setText(data.getPhone());

        view.setTag(data);

        return view;
    }

}

Try to modify your adapter's constructor like this:

public SelectPhoneContactAdapter(List<SelectPhoneContact> selectPhoneContacts, Context context) {
    theContactsList = selectPhoneContacts;
    _c = context;
    this.arraylist = new ArrayList<SelectPhoneContact>();
    this.arraylist.addAll(theContactsList);

    Collections.sort(this.arraylist, new Comparator<SelectPhoneContact>() {
        @Override
        public int compare(SelectPhoneContact t1, SelectPhoneContact t2) {
            if(t2.getPhone().equals("3456781276")) {   // put the phone number you want on top here
                return 1;
            } else {
                return t1.getName().compareTo(t2.getName());
            }
        }
    });
}

So we are basically sorting the ArrayList before the adapter starts using it.

So in this example, I am putting the phone number "3456781276" on top of everything else. If the phone number is NOT "3456781276", it will sort all the items by the name. (If you don't want to sort it by name, just remove the else statement.

Hope this helps.

EDIT:

in getView() , change:

final SelectPhoneContact data = (SelectPhoneContact) theContactsList.get(i);

to:

final SelectPhoneContact data = (SelectPhoneContact) arraylist.get(i);

Change getCount() method like this:

@Override
public int getCount() {
    return arraylist.size();
}

Change getItem() method like this:

@Override
public Object getItem(int i) {
    return arraylist.get(i);
}

You must use arraylist everywhere since that is the list we are sorting.

What about using add(int index, E element) ?

if (/* check your condition here: is it the number you are looking for? */) {
    // insert the contact at the beginning
    selectPhoneContacts.add(0, selectContact);
} else {
    // insert it at the end (default)
    selectPhoneContacts.add(selectContact);
}

An easy way to achieve this, just use a view in XML which contains your phone number, and set it to invisible in default, if the list shows, set the view to be visible. I hope this post help you!!!

You can easily manipulate with items positions in ArrayList with Collections.swap(); by looping through your contacts and by simply checking is number matching your number if does put it on the top for example: Collections.swap(myArrayList, i, 0);

Refering to: http://www.java2s.com/Code/Java/Collections-Data-Structure/SwapelementsofJavaArrayList.htm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM