搜索功能(支持全拼,首字母,不区分大小写,关键字变色等)

这篇博客介绍了如何在Android应用中实现搜索功能,包括支持全拼、首字母搜索,同时不区分大小写。通过使用pinyin4j库进行字符串转换,结合特定的计算关键字方法,优化了搜索体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上次写的可能有人说阅读性太差,所以改成这种编辑了

用到的工具主要是pinyin4j(compile ‘com.belerweb:pinyin4j:2.5.1’),将字符串转化成首字拼写或全拼,然后是计算关键字的方法.
- 1.首先是布局界面,可根据需求变更

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     xmlns:tools="http://schemas.android.com/tools"
  4.     android:id="@+id/activity_srearch"
  5.     android:orientation="vertical"
  6.     android:layout_width="match_parent"
  7.     android:layout_height="match_parent">
  8.     <LinearLayout
  9.         android:background="@color/white"
  10.         android:paddingTop="@dimen/status_bar_height"
  11.         android:orientation="horizontal"
  12.         android:gravity="center_vertical"
  13.         android:layout_width="match_parent"
  14.         android:layout_height="@dimen/activity_titleHeight">
  15.         <ImageView
  16.             android:id="@+id/iv_left"
  17.             android:padding="10dp"
  18.             android:src="@mipmap/back"
  19.             android:layout_width="wrap_content"
  20.             android:layout_height="wrap_content" />
  21.         <SearchView
  22.             android:gravity="center_vertical"
  23.             android:id="@+id/search_view"
  24.             android:layout_width="match_parent"
  25.             android:layout_height="match_parent"
  26.             android:iconifiedByDefault="false"
  27.             android:imeOptions="actionSearch"
  28.             android:queryHint="搜索" />
  29.     </LinearLayout>
  30.     <ListView
  31.         android:id="@+id/lv_search"
  32.         android:scrollbars="none"
  33.         android:layout_width="match_parent"
  34.         android:layout_height="match_parent"/>
  35. </LinearLayout>
  • 2.activity代码
    1. public class SearchActivity extends AppCompatActivity implements View.OnClickListener, SearchView.OnQueryTextListener, AdapterView.OnItemClickListener {
  2.     private SearchView search_view;
  3.     private ListView lv_search;
  4.     private Set infos;//这里的集合使用set,保证搜索结果的唯一性
  5.     private MyAdapter myAdapter;
  6.     private View iv_left;
  7.     @Override
  8.     public void onCreate(Bundle savedInstanceState) {
  9.         super.onCreate(savedInstanceState);
  10.         setContentView(R.layout.activity_srearch);
  11.         //沉浸式
  12.         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
  13.             getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
  14.             //getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
  15.         }
  16.         initView();
  17.         initData();
  18.         initAction();
  19.     }
  20.     public void initView() {
  21.         search_view = (SearchView) findViewById(R.id.search_view);
  22.         int id = search_view.getContext().getResources().getIdentifier("android:id/search_src_text", null, null);
  23.         TextView textView = (TextView) search_view.findViewById(id);
  24.         iv_left = findViewById(R.id.iv_left);
  25.         textView.setTextColor(UiUtil.getColor(R.color.blue_style));//字体颜色
  26.         textView.setTextSize(14);//字体、提示字体大小
  27.         textView.setHintTextColor(UiUtil.getColor(R.color.font_color_03));//提示字体颜色
  28.         try {//通过反射来设置背景效果
  29.             Class<?> argClass = search_view.getClass();
  30.             Field ownField = argClass.getDeclaredField("mSearchPlate");
  31.             ownField.setAccessible(true);
  32.             View mView = (View) ownField.get(search_view);
  33.             mView.setBackgroundColor(Color.WHITE);
  34.         } catch (Exception e) {
  35.             e.printStackTrace();
  36.         }
  37.         lv_search = (ListView) findViewById(R.id.lv_search);
  38.     }
  39.     public void initData() {
  40.         infos = new HashSet();
  41.         myAdapter = new MyAdapter();
  42.         lv_search.setAdapter(myAdapter);
  43.     }
  44.     public void initAction() {
  45.         search_view.setOnQueryTextListener(this);
  46.         lv_search.setOnItemClickListener(this);
  47.         iv_left.setOnClickListener(this);
  48.     }
  49.     /**
  50.      * 搜索
  51.      *
  52.      * @param query
  53.      * @return
  54.      */
  55.     @Override
  56.     public boolean onQueryTextSubmit(String query) {
  57.         return true;
  58.     }
  59.     private String search;//搜索文字的内容
  60.     /**
  61.      * 文字变化
  62.      *
  63.      * @param newText
  64.      * @return
  65.      */
  66.     @Override
  67.     public boolean onQueryTextChange(String newText) {
  68.         infos.clear();//搜索前清空原数据
  69.         search = newText;
  70.         if (TextUtils.isEmpty(newText)) {
  71.         } else {
  72.             int size = GlobleContent.departmentList.size();
  73.             for (int i = 0; i < size; i++) {
  74.                 DepartmentListBean bean = GlobleContent.departmentList.get(i);
  75.                 int count = bean.customUserList.size();
  76.                 for (int j = 0; j < count; j++) {
  77.                     CustomUserListBean bean1 = bean.customUserList.get(j);
  78.                     if (bean1.userName.contains(newText)) {
  79.                         bean1.type = 2;//姓名
  80.                         infos.add(bean1);
  81.                     }
  82.                     if (bean1.phoneNum.contains(newText)) {
  83.                         bean1.type = 3;//电话
  84.                         infos.add(bean1);
  85.                     }
  86.                     String firstSpell = UiUtil.getFirstSpell(bean1.userName);
  87.                     if (UiUtil.contain2(firstSpell, newText)) {//这个方法是重写String的比对方法,不区分大小写
  88.                         bean1.type = 4;//缩写
  89.                         infos.add(bean1);
  90.                     }
  91.                     String pingYin = UiUtil.getPingYin(bean1.userName);
  92.                     if (UiUtil.contain2(pingYin, newText)) {
  93.                         bean1.type = 5;//全拼
  94.                         infos.add(bean1);
  95.                     }
  96.                 }
  97.             }
  98.             int size1 = GlobleContent.ownerUserList.size();
  99.             for (int i = 0; i < size1; i++) {
  100.                 OwnerUserListBean bean = GlobleContent.ownerUserList.get(i);//业主的判断
  101.                 if (bean.unitName.contains(newText)) {
  102.                     bean.type = 1;//房号
  103.                     infos.add(bean);
  104.                 }
  105.                 if (bean.trueName.contains(newText)) {
  106.                     bean.type = 2;//姓名
  107.                     infos.add(bean);
  108.                 }
  109.                 if (bean.phone.contains(newText)) {
  110.                     bean.type = 3;//手机
  111.                     infos.add(bean);
  112.                 }
  113.                 String firstSpell = UiUtil.getFirstSpell(bean.trueName);
  114.                 if (UiUtil.contain2(firstSpell, newText)) {
  115.                     bean.type = 4;//缩写
  116.                     infos.add(bean);
  117.                 }
  118.                 String pingYin = UiUtil.getPingYin(bean.trueName);
  119.                 if (UiUtil.contain2(pingYin, newText)) {
  120.                     bean.type = 5;//全拼
  121.                     infos.add(bean);
  122.                 }
  123.             }
  124.         }
  125.         myAdapter.notifyDataSetChanged();
  126.         return false;
  127.     }
  128.     @Override
  129.     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
  130.         Intent intent = new Intent(SearchActivity.this, InfoActivity.class);
  131.         Object item = myAdapter.getItem(position);
  132.         intent.putExtra("info", (Serializable) item);
  133.         startActivity(intent);
  134.     }
  135.     @Override
  136.     public void onClick(View v) {
  137.         finish();
  138.     }
  139.     class MyAdapter extends BaseAdapter {
  140.         @Override
  141.         public int getCount() {
  142.             return infos.size();
  143.         }
  144.         @Override
  145.         public Object getItem(int position) {
  146.             Object[] objects = infos.toArray();
  147.             return objects[position];
  148.         }
  149.         @Override
  150.         public long getItemId(int position) {
  151.             return position;
  152.         }
  153.         @Override
  154.         public View getView(int position, View convertView, ViewGroup parent) {
  155.             ViewHolder holder;
  156.             if (convertView == null) {
  157.                 holder = new ViewHolder();
  158.                 convertView = View.inflate(parent.getContext(), R.layout.layout_item_child, null);
  159.                 holder.iv_photo = (ImageView) convertView.findViewById(R.id.iv_photo);
  160.                 holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
  161.                 holder.tv_num = (TextView) convertView.findViewById(R.id.tv_num);
  162.                 holder.tv_village = (TextView) convertView.findViewById(R.id.tv_village);
  163.                 convertView.setTag(holder);
  164.             } else {
  165.                 holder = (ViewHolder) convertView.getTag();
  166.             }
  167.             holder.tv_village.setVisibility(View.GONE);
  168.             Object item = getItem(position);
  169.             if (item instanceof CustomUserListBean) {
  170.                 CustomUserListBean info = (CustomUserListBean) item;
  171.                 switch (info.type) {//根据不同的条件展示不同的布局
  172.                     case 3://手机
  173.                         holder.tv_name.setText(info.userName);
  174.                         setColor(holder.tv_num, "手机号: " + info.phoneNum, 3);//这个方法用于查询关键字的变色
  175.                         break;
  176.                     case 2://姓名
  177.                         setColor(holder.tv_name, info.userName, 2);
  178.                         holder.tv_num.setText("部门: " + info.departmentName);
  179.                         break;
  180.                     case 4:
  181.                         setColor(holder.tv_name, info.userName, 4);
  182.                         holder.tv_num.setText("部门: " + info.departmentName);
  183.                         break;
  184.                     case 5:
  185.                         setColor(holder.tv_name, info.userName, 5);
  186.                         holder.tv_num.setText("部门: " + info.departmentName);
  187.                         break;
  188.                 }
  189.                 GlideUtils.loadImageView(UrlContext.IMG_BASE_URL + info.photo, holder.iv_photo);//使用glide加载图片
  190.             } else {
  191.                 OwnerUserListBean info = (OwnerUserListBean) item;
  192.                 switch (info.type) {
  193.                     case 1://房号
  194.                         setColor(holder.tv_name, info.unitName, 1);
  195.                         holder.tv_num.setText(info.identityName + ":" + info.trueName);
  196.                         break;
  197.                     case 3://手机
  198.                         holder.tv_name.setText(info.trueName);
  199.                         setColor(holder.tv_num, "手机号: " + info.phone, 3);
  200.                         break;
  201.                     case 2://姓名
  202.                         setColor(holder.tv_name, info.trueName, 2);
  203.                         holder.tv_num.setText("房号: " + info.unitName);
  204.                         break;
  205.                     case 4:
  206.                         setColor(holder.tv_name, info.trueName, 4);
  207.                         holder.tv_num.setText("房号: " + info.unitName);
  208.                         break;
  209.                     case 5:
  210.                         setColor(holder.tv_name, info.trueName, 5);
  211.                         holder.tv_num.setText("房号: " + info.unitName);
  212.                         break;
  213.                 }
  214.                 GlideUtils.loadImageView(UrlContext.IMG_BASE_URL + info.userImg, holder.iv_photo);
  215.             }
  216.             return convertView;
  217.         }
  218.         class ViewHolder {
  219.             ImageView iv_photo;
  220.             TextView tv_name;
  221.             TextView tv_num;
  222.             TextView tv_village;
  223.         }
  224.     }
  225.     public void setColor(TextView view, String text, int type) {
  226.         int index;
  227.         ForegroundColorSpan span = new ForegroundColorSpan(UiUtil.getColor(R.color.blue_style));//要显示的颜色
  228.         SpannableStringBuilder builder = new SpannableStringBuilder(text);
  229.         switch (type) {//不同的情况设置关键字变色
  230.             case 1:
  231.                 index = text.indexOf(search);
  232.                 if (index != -1) {
  233.                     builder.setSpan(span, index, index + search.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  234.                     view.setText(builder);
  235.                 } else {
  236.                     view.setText(builder);
  237.                 }
  238.                 break;
  239.             case 2:
  240.                 index = text.indexOf(search);
  241.                 if (index != -1) {
  242.                     builder.setSpan(span, index, index + search.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  243.                     view.setText(builder);
  244.                 } else {
  245.                     view.setText(builder);
  246.                 }
  247.                 break;
  248.             case 3:
  249.                 index = text.indexOf(search);
  250.                 if (index != -1) {
  251.                     builder.setSpan(span, index, index + search.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  252.                     view.setText(builder);
  253.                 } else {
  254.                     view.setText(builder);
  255.                 }
  256.                 break;
  257.             case 4://缩写
  258.                 String firstSpell = UiUtil.getFirstSpell(text);
  259.                 String lowerCase = search.toLowerCase();//全部转换为小写
  260.                 index = firstSpell.indexOf(lowerCase);
  261.                 if (index != -1) {
  262.                     builder.setSpan(span, index, index + search.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  263.                     view.setText(builder);
  264.                 } else {
  265.                     view.setText(text);
  266.                 }
  267.                 break;
  268.             case 5://全拼
  269.                 String lowerCase1 = search.toLowerCase();
  270.                 int count = text.length();
  271.                 int start = -1;
  272.                 int end = -1;
  273.                 for (int i = 1; i < count + 1; i++) {
  274.                     for (int j = 0; j < count; j++) {
  275.                         String sub = text.substring(j, j + i);
  276.                         String pinYin = UiUtil.getPingYin(sub);
  277.                         if (pinYin.contains(lowerCase1)) {
  278.                             start = j;
  279.                             end = j + i;
  280.                             i = count + 1;
  281.                             break;
  282.                         }
  283.                     }
  284.                 }
  285.                 if (start != -1 && end != -1) {
  286.                     builder.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  287.                     view.setText(builder);
  288.                 } else {
  289.                     view.setText(text);
  290.                 }
  291.                 break;
  292.         }
  293.     }
  294. }
  • 3.Util代码
  1. /**
  2.      * 将字符串中的中文转化为拼音,其他字符不变
  3.      *
  4.      * @param inputString
  5.      * @return
  6.      */
  7.     public static String getPingYin(String inputString) {
  8.         HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
  9.         format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
  10.         format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
  11.         format.setVCharType(HanyuPinyinVCharType.WITH_V);
  12.         char[] input = inputString.trim().toCharArray();
  13.         String output = "";
  14.         try {
  15.             for (char curchar : input) {
  16.                 if (Character.toString(curchar).matches(
  17.                         "[\\u4E00-\\u9FA5]+")) {
  18.                     String[] temp = PinyinHelper.toHanyuPinyinStringArray(
  19.                             curchar, format);
  20.                     output += temp[0];
  21.                 } else {
  22.                     output += Character.toString(curchar);
  23.                 }
  24.             }
  25.         } catch (BadHanyuPinyinOutputFormatCombination e) {
  26.             e.printStackTrace();
  27.         }
  28.         return output;
  29.     }
  30.     /**
  31.      * 汉字转换为汉语拼音首字母,英文字符不变
  32.      *
  33.      * @param chinese 汉字
  34.      * @return 拼音
  35.      */
  36.     public static String getFirstSpell(String chinese) {
  37.         StringBuffer pybf = new StringBuffer();
  38.         char[] arr = chinese.toCharArray();
  39.         HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
  40.         defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
  41.         defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
  42.         for (char curchar : arr) {
  43.             if (curchar > 128) {
  44.                 try {
  45.                     String[] temp = PinyinHelper.toHanyuPinyinStringArray(curchar, defaultFormat);
  46.                     if (temp != null) {
  47.                         pybf.append(temp[0].charAt(0));
  48.                     }
  49.                 } catch (BadHanyuPinyinOutputFormatCombination e) {
  50.                     e.printStackTrace();
  51.                 }
  52.             } else {
  53.                 pybf.append(curchar);
  54.             }
  55.         }
  56.         return pybf.toString().replaceAll("\\W", "").trim();
  57.     }
  58.     public static boolean contain2(String input, String regex) {
  59.         Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
  60.         Matcher m = p.matcher(input);
  61.         boolean result = m.find();
  62.         return result;
  63.     }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值