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

huangapple go评论101阅读模式
英文:

Allow both numeric and text filtering for Android SearchView

问题

  1. @Override
  2. public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) {
  3. menu.clear(); // 清除所有菜单项...
  4. inflater.inflate(R.menu.options_menu_contacts, menu);
  5. final MenuItem searchMenuItem = menu.findItem(R.id.search); // 搜索选项
  6. SearchView mSearchView = (SearchView) searchMenuItem.getActionView();
  7. // 设置过滤监听器
  8. mSearchView.setOnQueryTextListener(
  9. new SearchView.OnQueryTextListener() {
  10. @Override
  11. public boolean onQueryTextSubmit(String query) {
  12. return false;
  13. }
  14. @Override
  15. public boolean onQueryTextChange(String newText) {
  16. adapter.getFilter().filter(newText);
  17. return false;
  18. }
  19. });
  20. // TODO - 在搜索时隐藏用户卡片
  21. // 当按返回键时关闭 SearchView(而不仅仅是失去焦点)
  22. mSearchView.setOnQueryTextFocusChangeListener(
  23. (v, hasFocus) -> {
  24. // TODO - 在焦点变化时显示/隐藏用户卡片
  25. if (!hasFocus) {
  26. adapter.isSearchMode = false;
  27. searchMenuItem.collapseActionView();
  28. adapter.notifyDataSetChanged();
  29. } else {
  30. adapter.isSearchMode = true;
  31. searchMenuItem.collapseActionView();
  32. adapter.notifyDataSetChanged();
  33. }
  34. });
  35. super.onCreateOptionsMenu(menu, inflater);
  36. }
英文:

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:

  1. @Override
  2. public void onCreateOptionsMenu(final Menu menu, MenuInflater inflater) {
  3. menu.clear(); // clears all menu items..
  4. inflater.inflate(R.menu.options_menu_contacts, menu);
  5. final MenuItem searchMenuItem = menu.findItem(R.id.search); // search option
  6. SearchView mSearchView = (SearchView) searchMenuItem.getActionView();
  7. // Set the filtering listener
  8. mSearchView.setOnQueryTextListener(
  9. new SearchView.OnQueryTextListener() {
  10. @Override
  11. public boolean onQueryTextSubmit(String query) {
  12. return false;
  13. }
  14. @Override
  15. public boolean onQueryTextChange(String newText) {
  16. adapter.getFilter().filter(newText);
  17. return false;
  18. }
  19. });
  20. // TODO - hide the user card onSearch
  21. // Needed to close the SearchView when pressing back (instead of just losing focus)
  22. mSearchView.setOnQueryTextFocusChangeListener(
  23. (v, hasFocus) -> {
  24. // TODO - on focus change, show/hide user's card
  25. if (!hasFocus) {
  26. adapter.isSearchMode = false;
  27. searchMenuItem.collapseActionView();
  28. adapter.notifyDataSetChanged();
  29. } else {
  30. adapter.isSearchMode = true;
  31. searchMenuItem.collapseActionView();
  32. adapter.notifyDataSetChanged();
  33. }
  34. });
  35. super.onCreateOptionsMenu(menu, inflater);
  36. }

答案1

得分: 2

在你的适配器中:

  1. public class Adapter extends RecyclerView.Adapter<Viewholder> implements Filterable {
  2. private ArrayList<Contacts> contactArrayList = new ArrayList<>();
  3. private ArrayList<Contacts> mFilteredList = new ArrayList<>();
  4. private Context context;
  5. ...
  6. @Override
  7. public Filter getFilter() {
  8. return new Filter() {
  9. @Override
  10. protected FilterResults performFiltering(CharSequence charSequence) {
  11. String charString = charSequence.toString();
  12. if (charString.isEmpty()) {
  13. mFilteredList = contactArrayList;
  14. } else {
  15. ArrayList<Contacts> filteredList = new ArrayList<>();
  16. for (Contacts contact : contactArrayList) {
  17. if (contact.getNumber().toLowerCase().contains(charString.toLowerCase()) || events.getName().toLowerCase().contains(charString.toLowerCase())) {
  18. filteredList.add(contact);
  19. }
  20. }
  21. mFilteredList = filteredList;
  22. }
  23. FilterResults filterResults = new FilterResults();
  24. filterResults.values = mFilteredList;
  25. return filterResults;
  26. }
  27. @Override
  28. protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
  29. mFilteredList = (ArrayList<Contacts>) filterResults.values;
  30. notifyDataSetChanged();
  31. }
  32. };
  33. }
  34. }
英文:

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

In your adapter:

  1. public class Adapter extends RecyclerView.Adapter&lt;Viewholder&gt; implements Filterable {
  2. private ArrayList&lt;Contacts&gt; contactArrayList = new ArrayList&lt;&gt;();
  3. private ArrayList&lt;Contacts&gt; mFilteredList = new ArrayList&lt;&gt;();
  4. private Context context;
  5. ...
  6. @Override
  7. public Filter getFilter() {
  8. return new Filter() {
  9. @Override
  10. protected FilterResults performFiltering(CharSequence charSequence) {
  11. String charString = charSequence.toString();
  12. if (charString.isEmpty()) {
  13. mFilteredList = contactArrayList;
  14. } else {
  15. ArrayList&lt;Contacts&gt; filteredList = new ArrayList&lt;&gt;();
  16. for (Contacts contact : contactArrayList) {
  17. if (contact.getNumber().toLowerCase().contains(charString.toLowerCase()) || events.getName().toLowerCase().contains(charString.toLowerCase())) {
  18. filteredList.add(contact);
  19. }
  20. }
  21. mFilteredList = filteredList;
  22. }
  23. FilterResults filterResults = new FilterResults();
  24. filterResults.values = mFilteredList;
  25. return filterResults;
  26. }
  27. @Override
  28. protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
  29. mFilteredList = (ArrayList&lt;Contacts&gt;) filterResults.values;
  30. notifyDataSetChanged();
  31. }
  32. };
  33. }
  34. }
  35. </details>
  36. # 答案2
  37. **得分**: 0
  38. 这是你提供的代码的中文翻译:
  39. ```java
  40. **MainActivity**
  41. package app.personal.sampleapp;
  42. import android.content.ContentResolver;
  43. import android.database.Cursor;
  44. import android.graphics.Bitmap;
  45. import android.net.Uri;
  46. import android.os.AsyncTask;
  47. import android.os.Bundle;
  48. import android.provider.ContactsContract;
  49. import android.provider.MediaStore;
  50. import android.support.v7.app.AppCompatActivity;
  51. import android.support.v7.widget.SearchView;
  52. import android.support.v7.widget.Toolbar;
  53. import android.view.Menu;
  54. import android.view.MenuItem;
  55. import android.view.View;
  56. import android.widget.ListView;
  57. import android.widget.ProgressBar;
  58. import java.io.ByteArrayOutputStream;
  59. import java.io.FileNotFoundException;
  60. import java.io.IOException;
  61. import java.util.ArrayList;
  62. import java.util.List;
  63. public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, SearchView.OnQueryTextListener {
  64. protected Toolbar toolbar;
  65. private String id, name, phone, image_uri;
  66. private byte[] contactImage = null;
  67. private Bitmap bitmap;
  68. private int queryLength;
  69. private List<ContactItem> contactItems;
  70. private ListView listView;
  71. private ProgressBar progressBar;
  72. private ContactAdapter adapter;
  73. private SearchView searchView;
  74. private MenuItem searchMenuItem;
  75. @Override
  76. protected void onCreate(Bundle savedInstanceState) {
  77. super.onCreate(savedInstanceState);
  78. setContentView(R.layout.activity_main);
  79. init();
  80. new ContactInfo().execute();
  81. }
  82. private void init() {
  83. toolbar = (Toolbar) findViewById(R.id.tool_bar);
  84. setSupportActionBar(toolbar);
  85. listView = (ListView) findViewById(R.id.contact_list);
  86. progressBar = (ProgressBar) findViewById(R.id.progress_bar);
  87. }
  88. private void readContacts() {
  89. contactItems = new ArrayList<>();
  90. ContentResolver cr = getApplicationContext().getContentResolver();
  91. Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
  92. null, null, null);
  93. if (cur.getCount() > 0) {
  94. while (cur.moveToNext()) {
  95. ContactItem item = new ContactItem();
  96. id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
  97. name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
  98. name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
  99. image_uri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
  100. if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) {
  101. Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
  102. ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null);
  103. while (pCur.moveToNext()) {
  104. phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
  105. phone = phone.replaceAll("\\s+", "");
  106. phone = phone.replaceAll("[^0-9]", "");
  107. }
  108. pCur.close();
  109. }
  110. if (image_uri != null) {
  111. try {
  112. bitmap = MediaStore.Images.Media
  113. .getBitmap(getApplicationContext().getContentResolver(),
  114. Uri.parse(image_uri));
  115. contactImage = getImageBytes(bitmap);
  116. } catch (FileNotFoundException e) {
  117. e.printStackTrace();
  118. } catch (IOException e) {
  119. e.printStackTrace();
  120. }
  121. } else {
  122. contactImage = null;
  123. }
  124. item.setId(id);
  125. item.setName(name);
  126. item.setContactImage(contactImage);
  127. item.setPhone(phone);
  128. contactItems.add(item);
  129. }
  130. }
  131. }
  132. private byte[] getImageBytes(Bitmap bitmap) {
  133. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  134. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
  135. return outputStream.toByteArray();
  136. }
  137. @Override
  138. public boolean onCreateOptionsMenu(Menu menu) {
  139. getMenuInflater().inflate(R.menu.menu_search, menu);
  140. searchView = (SearchView) menu.findItem(R.id.search).getActionView();
  141. searchMenuItem = menu.findItem(R.id.search);
  142. searchView.setQueryHint(getResources().getString(R.string.type_here));
  143. searchView.setOnQueryTextFocusChangeListener(this);
  144. searchView.setOnQueryTextListener(this);
  145. return super.onCreateOptionsMenu(menu);
  146. }
  147. @Override
  148. public void onClick(View v) {
  149. }
  150. @Override
  151. public void onFocusChange(View v, boolean hasFocus) {
  152. if (!hasFocus) {
  153. searchMenuItem.collapseActionView();
  154. searchView.setQuery("", false);
  155. }
  156. }
  157. @Override
  158. public boolean onQueryTextSubmit(String query) {
  159. return false;
  160. }
  161. @Override
  162. public boolean onQueryTextChange(String newText) {
  163. queryLength = newText.length();
  164. adapter.getFilter().filter(newText);
  165. return false;
  166. }
  167. public class ContactInfo extends AsyncTask<Void, Void, Void> {
  168. @Override
  169. protected void onPreExecute() {
  170. super.onPreExecute();
  171. progressBar.setVisibility(View.VISIBLE);
  172. listView.setVisibility(View.GONE);
  173. }
  174. @Override
  175. protected Void doInBackground(Void... params) {
  176. readContacts();
  177. return null;
  178. }
  179. @Override
  180. protected void onPostExecute(Void aVoid) {
  181. super.onPostExecute(aVoid);
  182. progressBar.setVisibility(View.GONE);
  183. listView.setVisibility(View.VISIBLE);
  184. setListAdapter();
  185. }
  186. }
  187. private void setListAdapter() {
  188. adapter = new ContactAdapter(getApplicationContext(), contactItems);
  189. listView.setAdapter(adapter);
  190. }
  191. }
  192. **Create your customAdapter class:**
  193. import android.widget.Filter;
  194. import android.widget.Filterable;
  195. import android.widget.ImageView;
  196. import android.widget.TextView;
  197. import java.util.ArrayList;
  198. import java.util.List;
  199. public class ContactAdapter extends ArrayAdapter<ContactItem> implements Filterable {
  200. private Context context;
  201. private List<ContactItem> contacts, filterList;
  202. private LayoutInflater inflater;
  203. private ContactFilter filter;
  204. public ContactAdapter(Context context, List<ContactItem> contacts) {
  205. super(context, R.layout.contact_row, contacts);
  206. this.contacts = contacts;
  207. this.context = context;
  208. filterList = new ArrayList<>();
  209. this.filterList.addAll(contacts);
  210. }
  211. @Override
  212. public Filter getFilter() {
  213. if (filter == null)
  214. filter = new ContactFilter();
  215. return filter;
  216. }
  217. @Override
  218. public View getView(int position, View convertView, ViewGroup parent) {
  219. View view;
  220. ViewHolder viewHolder = new ViewHolder();
  221. if (convertView == null) {
  222. inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  223. view = inflater.inflate(R.layout.contact_row, parent, false);
  224. } else {
  225. view = convertView;
  226. }
  227. viewHolder.name = (TextView) view.findViewById(R.id.name);
  228. viewHolder.photo = (ImageView) view.findViewById(R.id.photo);
  229. viewHolder.number = (TextView) view.findViewById(R.id.phone);
  230. viewHolder.name.setText(contacts.get(position).getName());
  231. viewHolder.number.setText(contacts.get(position).getPhone());
  232. if ((contacts.get(position).getContactImage()) != null) {
  233. Bitmap contactImage = getContactImage(contacts.get(position).getContactImage());
  234. viewHolder.photo.setImageBitmap(contactImage);
  235. }else {
  236. viewHolder.photo.setImageResource(R.drawable.dummy_icon);
  237. }
  238. return view;
  239. }
  240. private Bitmap getContactImage(byte[] photo) {
  241. int targetW =
  242. <details>
  243. <summary>英文:</summary>
  244. **MainActivity**
  245. package app.personal.sampleapp;
  246. import android.content.ContentResolver;
  247. import android.database.Cursor;
  248. import android.graphics.Bitmap;
  249. import android.net.Uri;
  250. import android.os.AsyncTask;
  251. import android.os.Bundle;
  252. import android.provider.ContactsContract;
  253. import android.provider.MediaStore;
  254. import android.support.v7.app.AppCompatActivity;
  255. import android.support.v7.widget.SearchView;
  256. import android.support.v7.widget.Toolbar;
  257. import android.view.Menu;
  258. import android.view.MenuItem;
  259. import android.view.View;
  260. import android.widget.ListView;
  261. import android.widget.ProgressBar;
  262. import java.io.ByteArrayOutputStream;
  263. import java.io.FileNotFoundException;
  264. import java.io.IOException;
  265. import java.util.ArrayList;
  266. import java.util.List;
  267. public class MainActivity extends AppCompatActivity implements View.OnClickListener, View.OnFocusChangeListener, SearchView.OnQueryTextListener {
  268. protected Toolbar toolbar;
  269. private String id, name, phone, image_uri;
  270. private byte[] contactImage = null;
  271. private Bitmap bitmap;
  272. private int queryLength;
  273. private List&lt;ContactItem&gt; contactItems;
  274. private ListView listView;
  275. private ProgressBar progressBar;
  276. private ContactAdapter adapter;
  277. private SearchView searchView;
  278. private MenuItem searchMenuItem;
  279. @Override
  280. protected void onCreate(Bundle savedInstanceState) {
  281. super.onCreate(savedInstanceState);
  282. setContentView(R.layout.activity_main);
  283. init();
  284. new ContactInfo().execute();
  285. }
  286. private void init() {
  287. toolbar = (Toolbar) findViewById(R.id.tool_bar);
  288. setSupportActionBar(toolbar);
  289. listView = (ListView) findViewById(R.id.contact_list);
  290. progressBar = (ProgressBar) findViewById(R.id.progress_bar);
  291. }
  292. private void readContacts() {
  293. contactItems = new ArrayList&lt;&gt;();
  294. ContentResolver cr = getApplicationContext().getContentResolver();
  295. Cursor cur = cr.query(ContactsContract.Contacts.CONTENT_URI, null,
  296. null, null, null);
  297. if (cur.getCount() &gt; 0) {
  298. while (cur.moveToNext()) {
  299. ContactItem item = new ContactItem();
  300. id = cur.getString(cur.getColumnIndex(ContactsContract.Contacts._ID));
  301. name = cur.getString(cur.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
  302. name = Character.toUpperCase(name.charAt(0)) + name.substring(1);
  303. image_uri = cur.getString(cur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
  304. if (Integer.parseInt(cur.getString(cur.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) &gt; 0) {
  305. Cursor pCur = cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
  306. ContactsContract.CommonDataKinds.Phone.CONTACT_ID + &quot; = ?&quot;, new String[]{id}, null);
  307. while (pCur.moveToNext()) {
  308. phone = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
  309. phone = phone.replaceAll(&quot;\\s+&quot;, &quot;&quot;);
  310. phone = phone.replaceAll(&quot;[^0-9]&quot;, &quot;&quot;);
  311. }
  312. pCur.close();
  313. }
  314. if (image_uri != null) {
  315. try {
  316. bitmap = MediaStore.Images.Media
  317. .getBitmap(getApplicationContext().getContentResolver(),
  318. Uri.parse(image_uri));
  319. contactImage = getImageBytes(bitmap);
  320. } catch (FileNotFoundException e) {
  321. e.printStackTrace();
  322. } catch (IOException e) {
  323. e.printStackTrace();
  324. }
  325. } else {
  326. contactImage = null;
  327. }
  328. item.setId(id);
  329. item.setName(name);
  330. item.setContactImage(contactImage);
  331. item.setPhone(phone);
  332. contactItems.add(item);
  333. }
  334. }
  335. }
  336. private byte[] getImageBytes(Bitmap bitmap) {
  337. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  338. bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
  339. return outputStream.toByteArray();
  340. }
  341. @Override
  342. public boolean onCreateOptionsMenu(Menu menu) {
  343. getMenuInflater().inflate(R.menu.menu_search, menu);
  344. searchView = (SearchView) menu.findItem(R.id.search).getActionView();
  345. searchMenuItem = menu.findItem(R.id.search);
  346. searchView.setQueryHint(getResources().getString(R.string.type_here));
  347. searchView.setOnQueryTextFocusChangeListener(this);
  348. searchView.setOnQueryTextListener(this);
  349. return super.onCreateOptionsMenu(menu);
  350. }
  351. @Override
  352. public void onClick(View v) {
  353. }
  354. @Override
  355. public void onFocusChange(View v, boolean hasFocus) {
  356. if (!hasFocus) {
  357. searchMenuItem.collapseActionView();
  358. searchView.setQuery(&quot;&quot;, false);
  359. }
  360. }
  361. @Override
  362. public boolean onQueryTextSubmit(String query) {
  363. return false;
  364. }
  365. @Override
  366. public boolean onQueryTextChange(String newText) {
  367. queryLength = newText.length();
  368. adapter.getFilter().filter(newText);
  369. return false;
  370. }
  371. public class ContactInfo extends AsyncTask&lt;Void, Void, Void&gt; {
  372. @Override
  373. protected void onPreExecute() {
  374. super.onPreExecute();
  375. progressBar.setVisibility(View.VISIBLE);
  376. listView.setVisibility(View.GONE);
  377. }
  378. @Override
  379. protected Void doInBackground(Void... params) {
  380. readContacts();
  381. return null;
  382. }
  383. @Override
  384. protected void onPostExecute(Void aVoid) {
  385. super.onPostExecute(aVoid);
  386. progressBar.setVisibility(View.GONE);
  387. listView.setVisibility(View.VISIBLE);
  388. setListAdapter();
  389. }
  390. }
  391. private void setListAdapter() {
  392. adapter = new ContactAdapter(getApplicationContext(), contactItems);
  393. listView.setAdapter(adapter);
  394. }
  395. }
  396. **Create your customAdapter class:**
  397. import android.widget.Filter;
  398. import android.widget.Filterable;
  399. import android.widget.ImageView;
  400. import android.widget.TextView;
  401. import java.util.ArrayList;
  402. import java.util.List;
  403. public class ContactAdapter extends ArrayAdapter&lt;ContactItem&gt; implements Filterable {
  404. private Context context;
  405. private List&lt;ContactItem&gt; contacts, filterList;
  406. private LayoutInflater inflater;
  407. private ContactFilter filter;
  408. public ContactAdapter(Context context, List&lt;ContactItem&gt; contacts) {
  409. super(context, R.layout.contact_row, contacts);
  410. this.contacts = contacts;
  411. this.context = context;
  412. filterList = new ArrayList&lt;&gt;();
  413. this.filterList.addAll(contacts);
  414. }
  415. @Override
  416. public Filter getFilter() {
  417. if (filter == null)
  418. filter = new ContactFilter();
  419. return filter;
  420. }
  421. @Override
  422. public View getView(int position, View convertView, ViewGroup parent) {
  423. View view;
  424. ViewHolder viewHolder = new ViewHolder();
  425. if (convertView == null) {
  426. inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
  427. view = inflater.inflate(R.layout.contact_row, parent, false);
  428. } else {
  429. view = convertView;
  430. }
  431. viewHolder.name = (TextView) view.findViewById(R.id.name);
  432. viewHolder.photo = (ImageView) view.findViewById(R.id.photo);
  433. viewHolder.number = (TextView) view.findViewById(R.id.phone);
  434. viewHolder.name.setText(contacts.get(position).getName());
  435. viewHolder.number.setText(contacts.get(position).getPhone());
  436. if ((contacts.get(position).getContactImage()) != null) {
  437. Bitmap contactImage = getContactImage(contacts.get(position).getContactImage());
  438. viewHolder.photo.setImageBitmap(contactImage);
  439. }else {
  440. viewHolder.photo.setImageResource(R.drawable.dummy_icon);
  441. }
  442. return view;
  443. }
  444. private Bitmap getContactImage(byte[] photo) {
  445. int targetW = 50, targetH = 50;
  446. BitmapFactory.Options options = new BitmapFactory.Options();
  447. BitmapFactory.decodeByteArray(photo, 0, photo.length, options);
  448. options.inJustDecodeBounds = true;
  449. int imageW = options.outWidth;
  450. int imageH = options.outHeight;
  451. int scaleFactor = 1;
  452. if ((targetW &gt; 0) || (targetH &gt; 0)) {
  453. scaleFactor = Math.min(imageW / targetW, imageH / targetH);
  454. }
  455. options.inJustDecodeBounds = false;
  456. options.inSampleSize = scaleFactor;
  457. options.inPreferredConfig = Bitmap.Config.ARGB_8888;
  458. return BitmapFactory.decodeByteArray(photo, 0, photo.length, options);
  459. }
  460. public class ViewHolder {
  461. ImageView photo;
  462. TextView name, number;
  463. }
  464. private class ContactFilter extends Filter {
  465. @Override
  466. protected FilterResults performFiltering(CharSequence constraint) {
  467. String data = constraint.toString().toLowerCase();
  468. FilterResults results = new FilterResults();
  469. if (data.length() &gt; 0) {
  470. List&lt;ContactItem&gt; filteredList = new ArrayList&lt;&gt;(filterList);
  471. List&lt;ContactItem&gt; nList = new ArrayList&lt;&gt;();
  472. int count = filteredList.size();
  473. for (int i = 0; i &lt; count; i++) {
  474. ContactItem item = filteredList.get(i);
  475. String name = item.getName().toLowerCase();
  476. String phone = item.getPhone().toLowerCase();
  477. if (name.startsWith(data) || phone.startsWith(data))
  478. nList.add(item);
  479. }
  480. results.count = nList.size();
  481. results.values = nList;
  482. } else {
  483. List&lt;ContactItem&gt; list = new ArrayList&lt;&gt;(filterList);
  484. results.count = list.size();
  485. results.values = list;
  486. }
  487. return results;
  488. }
  489. @Override
  490. protected void publishResults(CharSequence constraint, FilterResults results) {
  491. contacts = (ArrayList&lt;ContactItem&gt;) results.values;
  492. clear();
  493. for (int i = 0; i &lt; contacts.size(); i++) {
  494. ContactItem item = (ContactItem) contacts.get(i);
  495. add(item);
  496. notifyDataSetChanged();
  497. }
  498. }
  499. }
  500. @Override
  501. public void notifyDataSetChanged() {
  502. super.notifyDataSetChanged();
  503. }
  504. }
  505. **Create POJO Class**
  506. public class ContactItem {
  507. private String id, name, phone;
  508. private byte[] contactImage = null;
  509. public String getId() {
  510. return id;
  511. }
  512. public void setId(String id) {
  513. this.id = id;
  514. }
  515. public String getName() {
  516. return name;
  517. }
  518. public void setName(String name) {
  519. this.name = name;
  520. }
  521. public String getPhone() {
  522. return phone;
  523. }
  524. public void setPhone(String phone) {
  525. this.phone = phone;
  526. }
  527. public byte[] getContactImage() {
  528. return contactImage;
  529. }
  530. public void setContactImage(byte[] contactImage) {
  531. this.contactImage = contactImage;
  532. }
  533. }
  534. **MainActivity.xml**
  535. &lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  536. xmlns:tools=&quot;http://schemas.android.com/tools&quot;
  537. android:layout_width=&quot;match_parent&quot;
  538. android:layout_height=&quot;match_parent&quot;
  539. android:orientation=&quot;vertical&quot;
  540. tools:context=&quot;.MainActivity&quot;&gt;
  541. &lt;FrameLayout
  542. android:id=&quot;@+id/frame_toolbar&quot;
  543. android:layout_width=&quot;match_parent&quot;
  544. android:layout_height=&quot;wrap_content&quot;
  545. android:layout_alignParentTop=&quot;true&quot;&gt;
  546. &lt;include
  547. android:id=&quot;@+id/tool_bar&quot;
  548. layout=&quot;@layout/toolbar&quot; /&gt;
  549. &lt;/FrameLayout&gt;
  550. &lt;ListView
  551. android:id=&quot;@+id/contact_list&quot;
  552. android:layout_width=&quot;match_parent&quot;
  553. android:layout_height=&quot;match_parent&quot;
  554. android:layout_below=&quot;@+id/frame_toolbar&quot;
  555. android:cacheColorHint=&quot;@android:color/transparent&quot;
  556. android:clipToPadding=&quot;false&quot;
  557. android:divider=&quot;@null&quot;
  558. android:dividerHeight=&quot;1dp&quot;
  559. android:listSelector=&quot;@android:color/transparent&quot; /&gt;
  560. &lt;ProgressBar
  561. android:id=&quot;@+id/progress_bar&quot;
  562. android:layout_width=&quot;wrap_content&quot;
  563. android:layout_height=&quot;wrap_content&quot;
  564. android:layout_centerInParent=&quot;true&quot; /&gt;
  565. &lt;/RelativeLayout&gt;
  566. **Create row Item layout file:**
  567. &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  568. &lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  569. android:layout_width=&quot;match_parent&quot;
  570. android:layout_height=&quot;wrap_content&quot;
  571. android:layout_gravity=&quot;center&quot;
  572. android:background=&quot;#FFF&quot;
  573. android:orientation=&quot;horizontal&quot;&gt;
  574. &lt;ImageView
  575. android:id=&quot;@+id/photo&quot;
  576. android:layout_width=&quot;50dp&quot;
  577. android:layout_height=&quot;50dp&quot; /&gt;
  578. &lt;LinearLayout
  579. android:layout_width=&quot;match_parent&quot;
  580. android:layout_height=&quot;wrap_content&quot;
  581. android:gravity=&quot;center_vertical&quot;
  582. android:orientation=&quot;horizontal&quot;
  583. android:weightSum=&quot;1&quot;&gt;
  584. &lt;LinearLayout
  585. android:layout_width=&quot;0dp&quot;
  586. android:layout_height=&quot;wrap_content&quot;
  587. android:layout_gravity=&quot;center_vertical&quot;
  588. android:layout_weight=&quot;1&quot;
  589. android:orientation=&quot;vertical&quot;&gt;
  590. &lt;TextView
  591. android:id=&quot;@+id/name&quot;
  592. android:layout_width=&quot;wrap_content&quot;
  593. android:layout_height=&quot;wrap_content&quot;
  594. android:layout_gravity=&quot;center_vertical&quot;
  595. android:layout_marginLeft=&quot;15dp&quot;
  596. android:textColor=&quot;#000000&quot;
  597. android:textSize=&quot;16sp&quot;
  598. android:textStyle=&quot;bold&quot; /&gt;
  599. &lt;TextView
  600. android:id=&quot;@+id/phone&quot;
  601. android:layout_width=&quot;wrap_content&quot;
  602. android:layout_height=&quot;wrap_content&quot;
  603. android:layout_gravity=&quot;center_vertical&quot;
  604. android:layout_marginLeft=&quot;15dp&quot;
  605. android:layout_marginTop=&quot;5dp&quot;
  606. android:textColor=&quot;#000000&quot;
  607. android:textSize=&quot;14sp&quot; /&gt;
  608. &lt;/LinearLayout&gt;
  609. &lt;/LinearLayout&gt;
  610. &lt;/LinearLayout&gt;
  611. **toolbar.xml**
  612. &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  613. &lt;android.support.v7.widget.Toolbar xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  614. xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;
  615. android:layout_width=&quot;match_parent&quot;
  616. android:layout_height=&quot;50dp&quot;
  617. android:background=&quot;#f57c00&quot;
  618. app:theme=&quot;@style/ThemeOverlay.AppCompat.Dark&quot; /&gt;
  619. **Create menu_search.xml in menu folder:**
  620. &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
  621. &lt;menu xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
  622. xmlns:app=&quot;http://schemas.android.com/apk/res-auto&quot;&gt;
  623. &lt;item
  624. android:id=&quot;@+id/search&quot;
  625. android:icon=&quot;@drawable/search&quot;
  626. android:title=&quot;@string/search_view&quot;
  627. app:actionViewClass=&quot;android.support.v7.widget.SearchView&quot;
  628. app:showAsAction=&quot;collapseActionView|always&quot; /&gt;
  629. &lt;/menu&gt;
  630. **add below code in style.xml file:**
  631. &lt;style name=&quot;NoActionBar&quot; parent=&quot;Theme.AppCompat.Light.NoActionBar&quot;&gt;
  632. &lt;item name=&quot;actionOverflowMenuStyle&quot;&gt;@style/PopupMenu&lt;/item&gt;
  633. &lt;/style&gt;
  634. &lt;style name=&quot;PopupMenu&quot; parent=&quot;Widget.AppCompat.PopupMenu.Overflow&quot;&gt;
  635. &lt;item name=&quot;android:textColor&quot;&gt;#FFF&lt;/item&gt;
  636. &lt;/style&gt;
  637. **add below code in AndroidManifest.xml**:
  638. android:theme=&quot;@style/NoActionBar&quot; // add in application theme
  639. &lt;uses-permission android:name=&quot;android.permission.READ_CONTACTS&quot; /&gt;
  640. &lt;uses-permission android:name=&quot;android.permission.WRITE_CONTACTS&quot; /&gt;
  641. </details>

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

发表评论

匿名网友

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

确定