允许在 Android SearchView 中进行数字和文本过滤。

huangapple 未分类评论47阅读模式
英文:

Allow both numeric and text filtering for Android SearchView

问题

@Override
    public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) {
        menu.clear(); // 清除所有菜单项...
        inflater.inflate(R.menu.options_menu_contacts, menu);

        final MenuItem searchMenuItem = menu.findItem(R.id.search); // 搜索选项

        SearchView mSearchView = (SearchView) searchMenuItem.getActionView();
        // 设置过滤监听器
        mSearchView.setOnQueryTextListener(
                new SearchView.OnQueryTextListener() {
                    @Override
                    public boolean onQueryTextSubmit(String query) {
                        return false;
                    }

                    @Override
                    public boolean onQueryTextChange(String newText) {
                        adapter.getFilter().filter(newText);
                        return false;
                    }
                });

        // TODO - 在搜索时隐藏用户卡片

        // 当按返回键时关闭 SearchView(而不仅仅是失去焦点)
        mSearchView.setOnQueryTextFocusChangeListener(
                (v, hasFocus) -> {
                    // TODO - 在焦点变化时显示/隐藏用户卡片
                    if (!hasFocus) {
                        adapter.isSearchMode = false;
                        searchMenuItem.collapseActionView();
                        adapter.notifyDataSetChanged();
                    } else {
                        adapter.isSearchMode = true;
                        searchMenuItem.collapseActionView();
                        adapter.notifyDataSetChanged();
                    }
                });

        super.onCreateOptionsMenu(menu, inflater);
    }
英文:

How can I allow the user to filter their Contacts list using both text and numbers? This is such that the user can search for a contact based both on their names and phone number.

Below my current code for clarity:

@Override
    public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) {
        menu.clear(); // clears all menu items..
        inflater.inflate(R.menu.options_menu_contacts, menu);

        final MenuItem searchMenuItem = menu.findItem(R.id.search); // search option

        SearchView mSearchView = (SearchView) searchMenuItem.getActionView();
        // Set the filtering listener
        mSearchView.setOnQueryTextListener(
                new SearchView.OnQueryTextListener() {
                    @Override
                    public boolean onQueryTextSubmit(String query) {
                        return false;
                    }

                    @Override
                    public boolean onQueryTextChange(String newText) {
                        adapter.getFilter().filter(newText);
                        return false;
                    }
                });

        // TODO - hide the user card onSearch

        // Needed to close the SearchView when pressing back (instead of just losing focus)
        mSearchView.setOnQueryTextFocusChangeListener(
                (v, hasFocus) -> {
                    // TODO - on focus change, show/hide user's card
                    if (!hasFocus) {
                        adapter.isSearchMode = false;
                        searchMenuItem.collapseActionView();
                        adapter.notifyDataSetChanged();
                    } else {
                        adapter.isSearchMode = true;
                        searchMenuItem.collapseActionView();
                        adapter.notifyDataSetChanged();
                    }
                });

        super.onCreateOptionsMenu(menu, inflater);
    }

答案1

得分: 2

在你的适配器中:

public class Adapter extends RecyclerView.Adapter<Viewholder> implements Filterable {
    private ArrayList<Contacts> contactArrayList = new ArrayList<>();
    private ArrayList<Contacts> mFilteredList = new ArrayList<>();
    private Context context;

    ...
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {

                String charString = charSequence.toString();

                if (charString.isEmpty()) {

                    mFilteredList = contactArrayList;
                } else {
                    ArrayList<Contacts> filteredList = new ArrayList<>();

                    for (Contacts contact : contactArrayList) {
                        if (contact.getNumber().toLowerCase().contains(charString.toLowerCase()) || events.getName().toLowerCase().contains(charString.toLowerCase())) {

                            filteredList.add(contact);
                        }
                    }

                    mFilteredList = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = mFilteredList;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                mFilteredList = (ArrayList<Contacts>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }
}
英文:

You can make a query on both the number as well as the contact name.

In your adapter:

public class Adapter extends RecyclerView.Adapter&lt;Viewholder&gt; implements Filterable {
    private ArrayList&lt;Contacts&gt; contactArrayList = new ArrayList&lt;&gt;();
    private ArrayList&lt;Contacts&gt; mFilteredList = new ArrayList&lt;&gt;();
    private Context context;

    ...
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {

                String charString = charSequence.toString();

                if (charString.isEmpty()) {

                    mFilteredList = contactArrayList;
                } else {
                    ArrayList&lt;Contacts&gt; filteredList = new ArrayList&lt;&gt;();

                    for (Contacts contact : contactArrayList) {
                        if (contact.getNumber().toLowerCase().contains(charString.toLowerCase()) || events.getName().toLowerCase().contains(charString.toLowerCase())) {

                            filteredList.add(contact);
                        }
                    }

                    mFilteredList = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = mFilteredList;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                mFilteredList = (ArrayList&lt;Contacts&gt;) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }
}


</details>



# 答案2
**得分**: 0

这是你提供的代码的中文翻译:

```java
**MainActivity**

        package app.personal.sampleapp;
    
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.SearchView;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.ListView;
    import android.widget.ProgressBar;
    import java.io.ByteArrayOutputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, SearchView.OnQueryTextListener {
    
    protected Toolbar toolbar;
    private String id, name, phone, image_uri;
    private byte[] contactImage = null;
    private Bitmap bitmap;
    private int queryLength;
    private List<ContactItem> contactItems;
    private ListView listView;
    private ProgressBar progressBar;
    private ContactAdapter adapter;
    private SearchView searchView;
    private MenuItem searchMenuItem;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        new ContactInfo().execute();
    
    }
    
    private void init() {
        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);
        listView = (ListView) findViewById(R.id.contact_list);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
    }
    
    
    private void readContacts() {
        contactItems = new ArrayList<>();
        ContentResolver cr = getApplicationContext().getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                null, null, null);
        if (cur.getCount() > 0) {
            while (cur.moveToNext()) {
                ContactItem item = new ContactItem();
                id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
                image_uri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
                    while (pCur.moveToNext()) {
                        phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        phone = phone.replaceAll("\\s+", "");
                        phone = phone.replaceAll("[^0-9]", "");
                    }
                    pCur.close();
                }
                if (image_uri != null) {
                    try {
                        bitmap = MediaStore.Images.Media
                                .getBitmap(getApplicationContext().getContentResolver(),
                                        Uri.parse(image_uri));
                        contactImage = getImageBytes(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    contactImage = null;
                }
                item.setId(id);
                item.setName(name);
                item.setContactImage(contactImage);
                item.setPhone(phone);
                contactItems.add(item);
            }
        }
    }
    
    private byte[] getImageBytes(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        return outputStream.toByteArray();
    }
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_search, menu);
        searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchMenuItem = menu.findItem(R.id.search);
        searchView.setQueryHint(getResources().getString(R.string.type_here));
        searchView.setOnQueryTextFocusChangeListener(this);
        searchView.setOnQueryTextListener(this);
        return super.onCreateOptionsMenu(menu);
    
    }
    
    @Override
    public void onClick(View v) {
    
    }
    
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            searchMenuItem.collapseActionView();
            searchView.setQuery("", false);
        }
    }
    
    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }
    
    @Override
    public boolean onQueryTextChange(String newText) {
        queryLength = newText.length();
        adapter.getFilter().filter(newText);
        return false;
    }
    
    public class ContactInfo extends AsyncTask<Void, Void, Void> {
    
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressBar.setVisibility(View.VISIBLE);
            listView.setVisibility(View.GONE);
        }
    
        @Override
        protected Void doInBackground(Void... params) {
            readContacts();
            return null;
        }
    
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            progressBar.setVisibility(View.GONE);
            listView.setVisibility(View.VISIBLE);
            setListAdapter();
        }
    }
    
    private void setListAdapter() {
        adapter = new ContactAdapter(getApplicationContext(), contactItems);
        listView.setAdapter(adapter);
    }
    }


**Create your customAdapter class:**


    import android.widget.Filter;
    import android.widget.Filterable;
    import android.widget.ImageView;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ContactAdapter extends ArrayAdapter<ContactItem> implements Filterable {
    
    private Context context;
    private List<ContactItem> contacts, filterList;
    private LayoutInflater inflater;
    private ContactFilter filter;
    
    public ContactAdapter(Context context, List<ContactItem> contacts) {
        super(context, R.layout.contact_row, contacts);
        this.contacts = contacts;
        this.context = context;
        filterList = new ArrayList<>();
        this.filterList.addAll(contacts);
    }
    
    
    @Override
    public Filter getFilter() {
        if (filter == null)
            filter = new ContactFilter();
        return filter;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        ViewHolder viewHolder = new ViewHolder();
        if (convertView == null) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.contact_row, parent, false);
        } else {
            view = convertView;
        }
        viewHolder.name = (TextView) view.findViewById(R.id.name);
        viewHolder.photo = (ImageView) view.findViewById(R.id.photo);
        viewHolder.number = (TextView) view.findViewById(R.id.phone);
        viewHolder.name.setText(contacts.get(position).getName());
        viewHolder.number.setText(contacts.get(position).getPhone());
        if ((contacts.get(position).getContactImage()) != null) {
            Bitmap contactImage = getContactImage(contacts.get(position).getContactImage());
            viewHolder.photo.setImageBitmap(contactImage);
        }else {
            viewHolder.photo.setImageResource(R.drawable.dummy_icon);
        }
        return view;
    }
    
    private Bitmap getContactImage(byte[] photo) {
        int targetW =

<details>
<summary>英文:</summary>

**MainActivity**

        package app.personal.sampleapp;
    
    import android.content.ContentResolver;
    import android.database.Cursor;
    import android.graphics.Bitmap;
    import android.net.Uri;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.provider.ContactsContract;
    import android.provider.MediaStore;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.SearchView;
    import android.support.v7.widget.Toolbar;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.view.View;
    import android.widget.ListView;
    import android.widget.ProgressBar;
    import java.io.ByteArrayOutputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity implements   View.OnClickListener, View.OnFocusChangeListener, SearchView.OnQueryTextListener {
    
    protected Toolbar toolbar;
    private String id, name, phone, image_uri;
    private byte[] contactImage = null;
    private Bitmap bitmap;
    private int queryLength;
    private List&lt;ContactItem&gt; contactItems;
    private ListView listView;
    private ProgressBar progressBar;
    private ContactAdapter adapter;
    private SearchView searchView;
    private MenuItem searchMenuItem;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        new ContactInfo().execute();
    
    }
    
    private void init() {
        toolbar = (Toolbar) findViewById(R.id.tool_bar);
        setSupportActionBar(toolbar);
        listView = (ListView) findViewById(R.id.contact_list);
        progressBar = (ProgressBar) findViewById(R.id.progress_bar);
    }
    
    
    private void readContacts() {
        contactItems = new ArrayList&lt;&gt;();
        ContentResolver cr = getApplicationContext().getContentResolver();
        Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
                null, null, null);
        if (cur.getCount() &gt; 0) {
            while (cur.moveToNext()) {
                ContactItem item = new ContactItem();
                id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
                name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
                image_uri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
                if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) &gt; 0) {
                    Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + &quot; = ?&quot;, new String[]{id}, null);
                    while (pCur.moveToNext()) {
                        phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                        phone = phone.replaceAll(&quot;\\s+&quot;, &quot;&quot;);
                        phone = phone.replaceAll(&quot;[^0-9]&quot;, &quot;&quot;);
                    }
                    pCur.close();
                }
                if (image_uri != null) {
                    try {
                        bitmap = MediaStore.Images.Media
                                .getBitmap(getApplicationContext().getContentResolver(),
                                        Uri.parse(image_uri));
                        contactImage = getImageBytes(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    contactImage = null;
                }
                item.setId(id);
                item.setName(name);
                item.setContactImage(contactImage);
                item.setPhone(phone);
                contactItems.add(item);
            }
        }
    }
    
    private byte[] getImageBytes(Bitmap bitmap) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
        return outputStream.toByteArray();
    }
    
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_search, menu);
        searchView = (SearchView) menu.findItem(R.id.search).getActionView();
        searchMenuItem = menu.findItem(R.id.search);
        searchView.setQueryHint(getResources().getString(R.string.type_here));
        searchView.setOnQueryTextFocusChangeListener(this);
        searchView.setOnQueryTextListener(this);
        return super.onCreateOptionsMenu(menu);
    
    }
    
    @Override
    public void onClick(View v) {
    
    }
    
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (!hasFocus) {
            searchMenuItem.collapseActionView();
            searchView.setQuery(&quot;&quot;, false);
        }
    }
    
    @Override
    public boolean onQueryTextSubmit(String query) {
        return false;
    }
    
    @Override
    public boolean onQueryTextChange(String newText) {
        queryLength = newText.length();
        adapter.getFilter().filter(newText);
        return false;
    }
    
    public class ContactInfo extends AsyncTask&lt;Void, Void, Void&gt; {
    
    
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            progressBar.setVisibility(View.VISIBLE);
            listView.setVisibility(View.GONE);
        }
    
        @Override
        protected Void doInBackground(Void... params) {
            readContacts();
            return null;
        }
    
        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            progressBar.setVisibility(View.GONE);
            listView.setVisibility(View.VISIBLE);
            setListAdapter();
        }
    }
    
    private void setListAdapter() {
        adapter = new ContactAdapter(getApplicationContext(), contactItems);
        listView.setAdapter(adapter);
    }
    }


**Create your customAdapter class:**


    import android.widget.Filter;
    import android.widget.Filterable;
    import android.widget.ImageView;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.List;
    
    public class ContactAdapter extends ArrayAdapter&lt;ContactItem&gt; implements Filterable {
    
    private Context context;
    private List&lt;ContactItem&gt; contacts, filterList;
    private LayoutInflater inflater;
    private ContactFilter filter;
    
    public ContactAdapter(Context context, List&lt;ContactItem&gt; contacts) {
        super(context, R.layout.contact_row, contacts);
        this.contacts = contacts;
        this.context = context;
        filterList = new ArrayList&lt;&gt;();
        this.filterList.addAll(contacts);
    }
    
    
    @Override
    public Filter getFilter() {
        if (filter == null)
            filter = new ContactFilter();
        return filter;
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view;
        ViewHolder viewHolder = new ViewHolder();
        if (convertView == null) {
            inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.contact_row, parent, false);
        } else {
            view = convertView;
        }
        viewHolder.name = (TextView) view.findViewById(R.id.name);
        viewHolder.photo = (ImageView) view.findViewById(R.id.photo);
        viewHolder.number = (TextView) view.findViewById(R.id.phone);
        viewHolder.name.setText(contacts.get(position).getName());
        viewHolder.number.setText(contacts.get(position).getPhone());
        if ((contacts.get(position).getContactImage()) != null) {
            Bitmap contactImage = getContactImage(contacts.get(position).getContactImage());
            viewHolder.photo.setImageBitmap(contactImage);
        }else {
            viewHolder.photo.setImageResource(R.drawable.dummy_icon);
        }
        return view;
    }
    
    private Bitmap getContactImage(byte[] photo) {
        int targetW = 50, targetH = 50;
        BitmapFactory.Options options = new BitmapFactory.Options();
        BitmapFactory.decodeByteArray(photo, 0, photo.length, options);
        options.inJustDecodeBounds = true;
        int imageW = options.outWidth;
        int imageH = options.outHeight;
        int scaleFactor = 1;
        if ((targetW &gt; 0) || (targetH &gt; 0)) {
            scaleFactor = Math.min(imageW / targetW, imageH / targetH);
        }
        options.inJustDecodeBounds = false;
        options.inSampleSize = scaleFactor;
        options.inPreferredConfig = Bitmap.Config.ARGB_8888;
        return BitmapFactory.decodeByteArray(photo, 0, photo.length, options);
    }
    
    
    public class ViewHolder {
        ImageView photo;
        TextView name, number;
    }
    
    private class ContactFilter extends Filter {
    
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            String data = constraint.toString().toLowerCase();
            FilterResults results = new FilterResults();
            if (data.length() &gt; 0) {
                List&lt;ContactItem&gt; filteredList = new ArrayList&lt;&gt;(filterList);
                List&lt;ContactItem&gt; nList = new ArrayList&lt;&gt;();
                int count = filteredList.size();
                for (int i = 0; i &lt; count; i++) {
                    ContactItem item = filteredList.get(i);
                    String name = item.getName().toLowerCase();
                    String phone = item.getPhone().toLowerCase();
                    if (name.startsWith(data) || phone.startsWith(data))
                        nList.add(item);
                }
                results.count = nList.size();
                results.values = nList;
            } else {
                List&lt;ContactItem&gt; list = new ArrayList&lt;&gt;(filterList);
                results.count = list.size();
                results.values = list;
            }
            return results;
        }
    
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            contacts = (ArrayList&lt;ContactItem&gt;) results.values;
            clear();
            for (int i = 0; i &lt; contacts.size(); i++) {
                ContactItem item = (ContactItem) contacts.get(i);
                add(item);
                notifyDataSetChanged();
            }
        }
    }
    
    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }
    }

**Create POJO Class**


    public class ContactItem {
    private String id, name, phone;
    private byte[] contactImage = null;
    
    public String getId() {
        return id;
    }
    
    public void setId(String id) {
        this.id = id;
    }
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getPhone() {
        return phone;
    }
    
    public void setPhone(String phone) {
        this.phone = phone;
    }
    
    public byte[] getContactImage() {
        return contactImage;
    }
    
    public void setContactImage(byte[] contactImage) {
        this.contactImage = contactImage;
    }
    }

**MainActivity.xml**

    &lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:tools=&quot;http://schemas.android.com/tools&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;match_parent&quot;
    android:orientation=&quot;vertical&quot;
    tools:context=&quot;.MainActivity&quot;&gt;
    
    &lt;FrameLayout
        android:id=&quot;@+id/frame_toolbar&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_alignParentTop=&quot;true&quot;&gt;
    
        &lt;include
            android:id=&quot;@+id/tool_bar&quot;
            layout=&quot;@layout/toolbar&quot; /&gt;
    &lt;/FrameLayout&gt;
    
    &lt;ListView
        android:id=&quot;@+id/contact_list&quot;
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;match_parent&quot;
        android:layout_below=&quot;@+id/frame_toolbar&quot;
        android:cacheColorHint=&quot;@android:color/transparent&quot;
        android:clipToPadding=&quot;false&quot;
        android:divider=&quot;@null&quot;
        android:dividerHeight=&quot;1dp&quot;
        android:listSelector=&quot;@android:color/transparent&quot; /&gt;
    
    &lt;ProgressBar
        android:id=&quot;@+id/progress_bar&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_centerInParent=&quot;true&quot; /&gt;
    
    &lt;/RelativeLayout&gt;

**Create row Item layout file:**

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
    &lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;wrap_content&quot;
    android:layout_gravity=&quot;center&quot;
    android:background=&quot;#FFF&quot;
    android:orientation=&quot;horizontal&quot;&gt;
    
    &lt;ImageView
        android:id=&quot;@+id/photo&quot;
        android:layout_width=&quot;50dp&quot;
        android:layout_height=&quot;50dp&quot; /&gt;
    
    &lt;LinearLayout
        android:layout_width=&quot;match_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:gravity=&quot;center_vertical&quot;
        android:orientation=&quot;horizontal&quot;
        android:weightSum=&quot;1&quot;&gt;
    
        &lt;LinearLayout
            android:layout_width=&quot;0dp&quot;
            android:layout_height=&quot;wrap_content&quot;
            android:layout_gravity=&quot;center_vertical&quot;
            android:layout_weight=&quot;1&quot;
            android:orientation=&quot;vertical&quot;&gt;
    
            &lt;TextView
                android:id=&quot;@+id/name&quot;
                android:layout_width=&quot;wrap_content&quot;
                android:layout_height=&quot;wrap_content&quot;
                android:layout_gravity=&quot;center_vertical&quot;
                android:layout_marginLeft=&quot;15dp&quot;
                android:textColor=&quot;#000000&quot;
                android:textSize=&quot;16sp&quot;
                android:textStyle=&quot;bold&quot; /&gt;
    
            &lt;TextView
                android:id=&quot;@+id/phone&quot;
                android:layout_width=&quot;wrap_content&quot;
                android:layout_height=&quot;wrap_content&quot;
                android:layout_gravity=&quot;center_vertical&quot;
                android:layout_marginLeft=&quot;15dp&quot;
                android:layout_marginTop=&quot;5dp&quot;
                android:textColor=&quot;#000000&quot;
                android:textSize=&quot;14sp&quot; /&gt;
        &lt;/LinearLayout&gt;
    &lt;/LinearLayout&gt;
    &lt;/LinearLayout&gt;

**toolbar.xml**


    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
    &lt;android.support.v7.widget.Toolbar xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
    android:layout_width=&quot;match_parent&quot;
    android:layout_height=&quot;50dp&quot;
    android:background=&quot;#f57c00&quot;
    app:theme=&quot;@style/ThemeOverlay.AppCompat.Dark&quot; /&gt;


**Create menu_search.xml in menu folder:**

    &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
    &lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;
    &lt;item
        android:id=&quot;@+id/search&quot;
        android:icon=&quot;@drawable/search&quot;
        android:title=&quot;@string/search_view&quot;
        app:actionViewClass=&quot;android.support.v7.widget.SearchView&quot;
        app:showAsAction=&quot;collapseActionView|always&quot; /&gt;
    &lt;/menu&gt;

**add below code in style.xml file:**

    &lt;style name=&quot;NoActionBar&quot; parent=&quot;Theme.AppCompat.Light.NoActionBar&quot;&gt;
        &lt;item name=&quot;actionOverflowMenuStyle&quot;&gt;@style/PopupMenu&lt;/item&gt;
    &lt;/style&gt;
    &lt;style name=&quot;PopupMenu&quot; parent=&quot;Widget.AppCompat.PopupMenu.Overflow&quot;&gt;
        &lt;item name=&quot;android:textColor&quot;&gt;#FFF&lt;/item&gt;
    &lt;/style&gt;

**add below code in AndroidManifest.xml**:

 

    android:theme=&quot;@style/NoActionBar&quot;  // add in application theme 
    
    &lt;uses-permission android:name=&quot;android.permission.READ_CONTACTS&quot; /&gt;
    &lt;uses-permission android:name=&quot;android.permission.WRITE_CONTACTS&quot; /&gt;



</details>



huangapple
  • 本文由 发表于 2020年5月4日 16:22:32
  • 转载请务必保留本文链接:https://java.coder-hub.com/61587930.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定