您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關android應用中如何實現一個通過拼音搜索文字的功能,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
第一步:準備
第二步:分析功能并實現
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:padding="16dp"> <EditText android:id="@+id/etSearchName" android:layout_width="match_parent" android:layout_height="50dp" android:hint="請輸入拼音" android:padding="5dp" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" app:layout_constraintTop_toBottomOf="@+id/etSearchName" /> </androidx.constraintlayout.widget.ConstraintLayout>
就一個搜索框和列表控件
接著創建列表適配器 SearchAdapter.java,實現了過濾器類Filterable
public class SearchAdapter extends RecyclerView.Adapter<SearchAdapter.MyViewHolder> implements Filterable { private Context context; private List<String> list; //保存原有的數據 private List<String> originalList; private OnItemListener onItemListener; void setOnItemListener(OnItemListener onItemListener){ this.onItemListener = onItemListener; } private SearchFilter filter; SearchAdapter(Context context,List<String> list){ this.context =context; this.list = list; originalList = list; } @NonNull @Override public SearchAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(context).inflate(R.layout.item_rv_search,parent,false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull SearchAdapter.MyViewHolder holder, final int position) { holder.tvName.setText(list.get(position)); holder.itemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (onItemListener!=null){ onItemListener.onItem(list.get(position)); } } }); } @Override public int getItemCount() { return list==null?0:list.size(); } @Override public Filter getFilter() { if (filter==null){ filter = new SearchFilter(); } return filter; } class MyViewHolder extends RecyclerView.ViewHolder{ private TextView tvName; MyViewHolder(@NonNull View itemView) { super(itemView); tvName = itemView.findViewById(R.id.tvName); } } interface OnItemListener{ void onItem(String name); } class SearchFilter extends Filter{ @Override protected FilterResults performFiltering(CharSequence constraint) { //輸入框傳來的數據 constraint //用于保存過濾的結果 FilterResults filterResults = new FilterResults(); if (constraint==null || constraint.length()==0){ filterResults.values = originalList; filterResults.count = originalList.size(); }else { List<String> fList = new ArrayList<>(); String cons = constraint.toString().trim().toLowerCase(); for (String s : originalList) { //從首位開始匹配 if (s.startsWith(cons)){ fList.add(s); } } filterResults.values = fList; filterResults.count = fList.size(); } return filterResults; } @Override protected void publishResults(CharSequence constraint, FilterResults results) { list = (List<String>) results.values; notifyDataSetChanged(); } } }
這段代碼,重點是SearchFilter類的兩個方法
注意點:originalList 這個集合是用來保存原有數據的。因為list會隨著搜索結果而變化,我們每次的過濾都是需要用到原有的數據。
適配器寫好了,下面看看怎么使用它
private RecyclerView recyclerView; private SearchAdapter adapter; private List<String> list; private EditText etSearchName; public static final String[] str = new String[]{ "陳天麗","黃正","徐明" ,"李自成","林子祥","周星星" ,"周潤發","林星辰","林青霞" ,"李賽鳳","劉德華","胡歌" ,"霍建華","林心如","趙薇" ,"趙四","趙本山","郭德綱" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etSearchName = findViewById(R.id.etSearchName); recyclerView = findViewById(R.id.recyclerView); recyclerView.setLayoutManager(new LinearLayoutManager(this)); list = new ArrayList<>(); list.addAll(Arrays.asList(str)); adapter = new SearchAdapter(this,list); recyclerView.setAdapter(adapter); adapter.setOnItemListener(new SearchAdapter.OnItemListener() { @Override public void onItem(String name) { etSearchName.setText(name); } }); etSearchName.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { adapter.getFilter().filter(etSearchName.getText().toString().trim()); } @Override public void afterTextChanged(Editable s) { } }); }
一頓RecyclerView的常規操作
這里需要注意的是這段代碼 adapter.getFilter().filter(etSearchName.getText().toString().trim()); 這里就調用了我們寫好的過濾器。
到此,我們的搜索過濾功能已經實現了。
看看運行效果:
接下來說說中文轉拼音
首先需要修改數據源類型
HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat(); format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);//不顯示音標 format.setVCharType(HanyuPinyinVCharType.WITH_V);//“ü”輸出V format.setCaseType(HanyuPinyinCaseType.LOWERCASE);//拼音輸出小寫 userNameList = new ArrayList<>(); for (String name : list) { StringBuffer stringBuffer = new StringBuffer(); for (int j=0;j<name.length();j++){ char c = name.charAt(j); String[] cStrHY = new String[0]; try { cStrHY = PinyinHelper.toHanyuPinyinStringArray(c,format); } catch (BadHanyuPinyinOutputFormatCombination badHanyuPinyinOutputFormatCombination) { badHanyuPinyinOutputFormatCombination.printStackTrace(); } stringBuffer.append(cStrHY[0]); } UserName userName = new UserName(); userName.setPinyin(stringBuffer.toString()); userName.setName(name); userNameList.add(userName); }
PinyinHelper類有很多轉換的方法,我選擇了toHanyuPinyinStringArray,將單個字符轉成拼音
值得注意的是,HanyuPinyinOutputFormat類,可以用你輸出不同的拼音格式
setToneType 設置音標的顯示方式:
HanyuPinyinToneType.WITH_TONE_MARK:在拼音字母上顯示音標,如“zhòng”
HanyuPinyinToneType.WITH_TONE_NUMBER:在拼音字符串后面通過數字顯示,如“zhong4”
HanyuPinyinToneType.WITHOUT_TONE:不顯示音標
setCaseType 設置拼音大小寫:
HanyuPinyinCaseType.LOWERCASE:返回的拼音為小寫字母
HanyuPinyinCaseType.UPPERCASE:返回的拼音為大寫字母
setVCharType 設置拼音字母“ü”的顯示方式
漢語拼音中的“ü”不能簡單的通過英文來表示,所以需要單獨定義“ü”的顯示格式
HanyuPinyinVCharType.WITH_U_UNICODE:默認的顯示方式,輸出“ü”
HanyuPinyinVCharType.WITH_V:輸出“v”
HanyuPinyinVCharType.WITH_U_AND_COLON:輸出“u:”
所以過濾的判斷需要改一下,代碼如下:
List<UserName> fList = new ArrayList<>(); String cons = constraint.toString().trim().toLowerCase(); for (UserName userName : originalList) { //從首位開始匹配 if (userName.getPinyin().startsWith(cons)){ fList.add(userName); } } filterResults.values = fList; filterResults.count = fList.size();
看看運行效果:
總結:
這個拼音搜索功能還有待改進
1、拼音搜索的準確性,比如王重陽(wangzhongyang,wangchongyang)其實應該有兩種讀音,但是我現在項目只做了一種。
關于android應用中如何實現一個通過拼音搜索文字的功能就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。