您好,登錄后才能下訂單哦!
本篇內(nèi)容主要講解“Android怎么實現(xiàn)模擬搜索功能”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Android怎么實現(xiàn)模擬搜索功能”吧!
本文實例為大家分享了Android實現(xiàn)模擬搜索功能的具體代碼,供大家參考,具體內(nèi)容如下
先看效果圖,合適了再接著往下看:
我們看到的這個頁面,是由兩部分組成,頂部的自定義的搜索框,和listView組成。
首先我們來實現(xiàn)布局頁面,自定義搜索框,和設(shè)置listView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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=".SearchBoxActivity" android:orientation="vertical" > <EditText android:id="@+id/et_search" android:layout_width="match_parent" android:layout_height="40dp" android:hint="搜索名稱" android:background="@drawable/btn_search" android:layout_marginLeft="10dp" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:maxLines="1" android:maxLength="20" android:inputType="text" android:drawableLeft="@drawable/search" /> <ListView android:id="@+id/listView" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout>
其中EditeText控件中的 android:background="@drawable/btn_search"
這個btn_search.xml 是在drawable目錄下定義的。
btn_search.xml
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <padding android:bottom="5dp" android:left="5dp" android:right="5dp" android:top="5dp" /> <stroke android:width="2dp" android:color="@color/blue" /> <solid android:color="@color/white" /> <corners android:radius="20dp" /> </shape>
之后我們就來實現(xiàn)搜索搜索功能。
使用ListView控件就要給這個控件設(shè)置適配器,我們就先來創(chuàng)建一個適配器SearchAdapter,里面的list集合泛型是我自己創(chuàng)建的一個類,類里面只有一個String屬性,實現(xiàn)了get和set方法,還有構(gòu)造器。
在適配器中創(chuàng)建了一個內(nèi)部類MyFilter,繼承了Filter類,這個Filter類是Google官方提供的,實現(xiàn)數(shù)據(jù)過濾。之后我們重寫其中的兩個方法performFiltering 和publishResults 自己制定過濾規(guī)則。
public class SearchAdapter extends BaseAdapter implements Filterable { private Context context; private ArrayList<Simulation> list = new ArrayList<>(); private MyFilter filter; //創(chuàng)建MyFilter對象 private FilterListener listener = null; //接口對象 public SearchAdapter(Context context, ArrayList<Simulation> list, FilterListener listener) { this.context = context; this.list = list; this.listener = listener; } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { try { final ViewHold hold; if (convertView == null) { hold = new ViewHold(); convertView = LayoutInflater.from(context).inflate(R.layout.item_search, null); hold.tv_simulation = convertView.findViewById(R.id.tv_simulation); convertView.setTag(hold); } else { hold = (ViewHold) convertView.getTag(); } Simulation simulation = list.get(position); hold.tv_simulation.setText(simulation.getText()); } catch (Exception e) { e.printStackTrace(); } return convertView; } public Filter getFilter() { if (filter == null) { filter = new MyFilter(list); } return filter; } /** * 創(chuàng)建內(nèi)部類MyFilter繼承Filter類,并重寫相關(guān)方法,實現(xiàn)數(shù)據(jù)的過濾 */ class MyFilter extends Filter { //創(chuàng)建集合保存原始數(shù)據(jù) private ArrayList<Simulation> original = new ArrayList<>(); public MyFilter(ArrayList<Simulation> original) { this.original = original; } //該方法返回搜索過濾后的數(shù)據(jù) @Override protected FilterResults performFiltering(CharSequence constraint) { //創(chuàng)建FilterResults對象 FilterResults filterResults = new FilterResults(); /** * 沒有搜索內(nèi)容的話就還是給filterResults賦值原始數(shù)據(jù)的值和大小 * 執(zhí)行了搜索的話,根據(jù)搜索規(guī)則過濾即可,最后把過濾后的數(shù)據(jù)的值和大小賦值給filterResults */ if (TextUtils.isEmpty(constraint)) { //取出當(dāng)前的數(shù)據(jù)源的值和集合元素個數(shù) //此時返回的filterResults就是原始的數(shù)據(jù),不進(jìn)行過濾 filterResults.values = original; filterResults.count = original.size(); } else { ArrayList<Simulation> mList = new ArrayList<>(); //創(chuàng)建集合保護(hù)過濾后的數(shù)據(jù) for (Simulation s : original) { //這里的toLowerCase():是將字符串中的字母全部變?yōu)樾?,而非字母則不做改變 if (s.getText().trim().toLowerCase().contains(constraint.toString().trim().toLowerCase())) { //規(guī)則匹配的話就往集合中添加該數(shù)據(jù) mList.add(s); } } filterResults.values = mList; filterResults.count = mList.size(); } return filterResults; } //該方法用來刷新用戶界面,根據(jù)過濾后的數(shù)據(jù)重新展示列表 @Override protected void publishResults(CharSequence constraint, FilterResults results) { //獲取過濾后的數(shù)據(jù) list = (ArrayList<Simulation>) results.values; //如果接口對象不為空,那么調(diào)用接口中的方法獲取過濾后的數(shù)據(jù),具體的實現(xiàn)在new這個接口的時候重寫的方法里執(zhí)行 if (listener != null) { listener.getFilterData(list); } //刷新數(shù)據(jù)源顯示 //通知數(shù)據(jù)觀察者當(dāng)前所關(guān)聯(lián)的數(shù)據(jù)源已經(jīng)發(fā)生改變,任何與該數(shù)據(jù)有關(guān)的視圖都應(yīng)該去刷新自己。 notifyDataSetChanged(); } } public interface FilterListener{ void getFilterData(List<Simulation> list); } public final class ViewHold { private TextView tv_simulation; } }
之后我們在SearchBoxActivity中,對EditText控件的TextChanged進(jìn)行實時監(jiān)聽,然后對輸入的關(guān)鍵字與ListView中的數(shù)據(jù)源進(jìn)行循環(huán)遍歷、過濾,再把新數(shù)據(jù)源通過適配器刷新到ListView上。這么一個過程。
public class SearchBoxActivity extends AppCompatActivity { private static final String TAG = "SearchBoxActivity"; private EditText et_search; private ListView listView; private SearchAdapter searchAdapter; private ArrayList<Simulation> list = new ArrayList<>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search_box); et_search = findViewById(R.id.et_search); listView = findViewById(R.id.listView); String data[] = new String[]{"大數(shù)據(jù)", "Android開發(fā)", "Java開發(fā)", "web前端開發(fā)", "網(wǎng)頁開發(fā)", "IOS開發(fā)"}; for (int i = 0; i < 6; i++) { Simulation simulation = new Simulation(data[i]); list.add(simulation); } searchAdapter = new SearchAdapter(this, list, new SearchAdapter.FilterListener() { @Override public void getFilterData(List<Simulation> list) { //這里可以拿到過濾后的數(shù)據(jù),所以在這里可以對搜索后的數(shù)據(jù)進(jìn)行操作 Log.e(TAG, "接口回調(diào)成功"); Log.e(TAG, list.toString()); setItemClick(list); } }); //設(shè)置適配器 listView.setAdapter(searchAdapter); //設(shè)置監(jiān)聽 setListeners(); } private void setListeners() { //沒有進(jìn)行搜索的時候,也要添加對listView的item單擊監(jiān)聽 setItemClick(list); /** * 對編輯框添加文本改變監(jiān)聽,搜索的具體功能是在這里實現(xiàn) * 文字改變的時候進(jìn)行搜索,關(guān)鍵方法是重寫onTextChanged()方法 */ et_search.addTextChangedListener(new TextWatcher() { //每次EditText文本改變之前的時候,會回調(diào)這個方法 @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { //s 輸入框中改變前的字符串信息 //start 輸入框中改變前的字符串的起始位置 //count 輸入框中改變前后的字符串改變數(shù)量一般為0 //after 輸入框中改變后的字符串與起始位置的偏移量 } //每次EditText文本改變的時候,會回調(diào)這個方法 @Override public void onTextChanged(CharSequence s, int start, int before, int count) { //第一個參數(shù)s 的含義: 輸入框中改變后的字符串信息 //start 輸入框中改變后的字符串的起始位置 //before 輸入框中改變前的字符串的位置 默認(rèn)為0 //count 輸入框中改變后的一共輸入字符串的數(shù)量 if (searchAdapter != null) { searchAdapter.getFilter().filter(s); } } //每次EditText文本改變之后的時候,會回調(diào)這個方法 @Override public void afterTextChanged(Editable s) { //edit 輸入結(jié)束呈現(xiàn)在輸入框中的信息 } }); } private void setItemClick(List<Simulation> filter_list) { listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Toast.makeText(SearchBoxActivity.this, filter_list.get(position).getText(), Toast.LENGTH_SHORT).show(); } }); } }
這樣就實現(xiàn)了模擬搜索的功能,并且在代碼中已經(jīng)給出了詳細(xì)的注釋。
到此,相信大家對“Android怎么實現(xiàn)模擬搜索功能”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。