自定义搜索功能Android实现
程序员文章站
2024-03-01 19:41:58
先看看效果图:
源码下载:自定义搜索功能
代码:
searchactivity.java
package com.bzu.gxs.search.acti...
先看看效果图:
源码下载:自定义搜索功能
代码:
searchactivity.java
package com.bzu.gxs.search.activity; import android.app.activity; import android.os.bundle; import android.support.v7.widget.toolbar; import android.view.view; import android.widget.adapterview; import android.widget.arrayadapter; import android.widget.listview; import android.widget.toast; import com.bzu.gxs.search.r; import com.bzu.gxs.search.adapter.searchadapter; import com.bzu.gxs.search.bean.searchbean; import com.bzu.gxs.search.widget.searchview; import java.util.arraylist; import java.util.list; /** * 搜索 * created by gxs on 2016/5/6. */ public class searchactivity extends activity implements searchview.searchviewlistener{ /** * 搜索结果列表view */ private listview lvresults; /** * 搜索view */ private searchview searchview; /** * 热搜框列表adapter */ private arrayadapter<string> hintadapter; /** * 自动补全列表adapter */ private arrayadapter<string> autocompleteadapter; /** * 搜索结果列表adapter */ private searchadapter resultadapter; private list<searchbean> dbdata; /** * 热搜版数据 */ private list<string> hintdata; /** * 搜索过程中自动补全数据 */ private list<string> autocompletedata; /** * 搜索结果的数据 */ private list<searchbean> resultdata; /** * 默认提示框显示项的个数 */ private static int default_hint_size = 4; /** * 提示框显示项的个数 */ private static int hintsize = default_hint_size; /** * 设置提示框显示项的个数 * * @param hintsize 提示框显示个数 */ public static void sethintsize(int hintsize) { searchactivity.hintsize = hintsize; } @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initdata(); initviews(); } /** * 初始化视图 */ private void initviews() { lvresults = (listview) findviewbyid(r.id.main_lv_search_results); searchview = (searchview) findviewbyid(r.id.main_search_layout); //设置监听 searchview.setsearchviewlistener(this); //设置adapter searchview.settipshintadapter(hintadapter); searchview.setautocompleteadapter(autocompleteadapter); lvresults.setonitemclicklistener(new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int position, long l) { toast.maketext(searchactivity.this, position + "", toast.length_short).show(); } }); } /** * 初始化数据 */ private void initdata() { //从数据库获取数据 getdbdata(); //初始化热搜版数据 gethintdata(); //初始化自动补全数据 getautocompletedata(null); //初始化搜索结果数据 getresultdata(null); } /** * 获取db 数据 */ private void getdbdata() { int size = 100; dbdata = new arraylist<>(size); for (int i = 0; i < size; i++) { dbdata.add(new searchbean(r.mipmap.ic_launcher, "andrion stuidy 起风了," + (i + 1), "唯有努力才能生存!", i * 20 + 2 + "")); } } /** * 获取热搜版data 和adapter */ private void gethintdata() { hintdata = new arraylist<>(hintsize); for (int i = 1; i <= hintsize; i++) { hintdata.add("andrion stuidy 起风了"); } hintadapter = new arrayadapter<>(this, android.r.layout.simple_list_item_1, hintdata); } /** * 获取自动补全data 和adapter */ private void getautocompletedata(string text) { if (autocompletedata == null) { //初始化 autocompletedata = new arraylist<>(hintsize); } else { // 根据text 获取auto data autocompletedata.clear(); for (int i = 0, count = 0; i < dbdata.size() && count < hintsize; i++) { if (dbdata.get(i).gettitle().contains(text.trim())) { autocompletedata.add(dbdata.get(i).gettitle()); count++; } } } if (autocompleteadapter == null) { autocompleteadapter = new arrayadapter<>(this, android.r.layout.simple_list_item_1, autocompletedata); } else { autocompleteadapter.notifydatasetchanged(); } } /** * 获取搜索结果data和adapter */ private void getresultdata(string text) { if (resultdata == null) { // 初始化 resultdata = new arraylist<>(); } else { resultdata.clear(); for (int i = 0; i < dbdata.size(); i++) { if (dbdata.get(i).gettitle().contains(text.trim())) { resultdata.add(dbdata.get(i)); } } } if (resultadapter == null) { resultadapter = new searchadapter(this, resultdata, r.layout.item_search); } else { resultadapter.notifydatasetchanged(); } } //当搜索框 文本改变时 触发的回调 ,更新自动补全数据 @override public void onrefreshautocomplete(string text) { //更新数据 getautocompletedata(text); } //点击搜索键时edit text触发的回调 @override public void onsearch(string text) { //更新result数据 getresultdata(text); lvresults.setvisibility(view.visible); //第一次获取结果 还未配置适配器 if (lvresults.getadapter() == null) { //获取搜索数据 设置适配器 lvresults.setadapter(resultadapter); } else { //更新搜索数据 resultadapter.notifydatasetchanged(); } } }
searchbean.java
package com.bzu.gxs.search.bean; /** * created by gxs on 2016/5/9. */ public class searchbean { private int iconid; private string title; private string content; private string comments; public searchbean(int iconid,string title,string content,string comments){ this.iconid=iconid; this.title=title; this.content=content; this.comments=comments; } public int geticonid() { return iconid; } public void seticonid(int iconid) { this.iconid = iconid; } public void settitle(string title) { this.title = title; } public string gettitle() { return title; } public string getcontent() { return content; } public void setcontent(string content) { this.content = content; } public string getcomments() { return comments; } public void setcomments(string comments) { this.comments = comments; } }
searchadapter.java
package com.bzu.gxs.search.adapter; import android.content.context; import com.bzu.gxs.search.bean.searchbean; import java.util.list; import com.bzu.gxs.search.r; /** * created by gxs on 2016/5/9. */ public class searchadapter extends commonadapter<searchbean> { public searchadapter(context context, list<searchbean> data, int layoutid) { super(context, data, layoutid); } @override public void convert(viewholder holder, int position) { holder.setimageresource(r.id.item_search_iv_icon,mdata.get(position).geticonid()) .settext(r.id.item_search_tv_title,mdata.get(position).gettitle()) .settext(r.id.item_search_tv_content,mdata.get(position).getcontent()) .settext(r.id.item_search_tv_comments,mdata.get(position).getcomments()); } }
commonadapter.java
package com.bzu.gxs.search.adapter; import android.content.context; import android.view.view; import android.view.viewgroup; import android.widget.baseadapter; import java.util.list; /** * created by gxs on 2016/5/9. */ public abstract class commonadapter<t> extends baseadapter { protected context mcontext; protected list<t> mdata; protected int mlayoutid; public commonadapter(context context,list<t> data,int layoutid){ mcontext = context; mdata = data; mlayoutid = layoutid; } @override public int getcount() { return mdata.size(); } @override public object getitem(int position) { return mdata.get(position); } @override public long getitemid(int position) { return position; } @override public view getview(int position, view convertview, viewgroup parent) { viewholder holder = viewholder.getholder(mcontext,convertview,mlayoutid,parent,position); convert(holder,position); return holder.getconvertview(); } /** * get holder convert */ public abstract void convert(viewholder holder,int position); }
viewholder.java
package com.bzu.gxs.search.adapter; import android.content.context; import android.graphics.bitmap; import android.util.sparsearray; import android.view.layoutinflater; import android.view.view; import android.view.viewgroup; import android.widget.imageview; import android.widget.textview; /** * created by gxs on 2016/5/9. */ public class viewholder { private sparsearray<view> mviews; private context mcontext; private view mconvertview; private int mposition; /** * 初始化 holder */ public viewholder(context context, int layoutid, viewgroup parent, int position) { mconvertview = layoutinflater.from(context).inflate(layoutid,parent,false); mviews = new sparsearray<>(); mposition = position; mconvertview.settag(this); } /** * 获取 viewholder */ public static viewholder getholder(context context, view convertview, int layoutid, viewgroup parent, int position) { if(convertview == null){ return new viewholder(context,layoutid,parent,position); }else{ viewholder holder = (viewholder)convertview.gettag(); holder.mposition = position; return holder; } } public view getconvertview(){ return mconvertview; } /** * 获取 view */ public <t extends view> t getview(int viewid){ view view = mviews.get(viewid); if(view == null){ view = mconvertview.findviewbyid(viewid); mviews.put(viewid,view); } return (t)view; } /** * 设置 text */ public viewholder settext(int viewid, string text){ textview tv = getview(viewid); tv.settext(text); return this; } /** * 设置图片资源 */ public viewholder setimageresource(int viewid,int resid){ imageview iv = getview(viewid); iv.setimageresource(resid); return this; } /** * 设置图片 bitmap */ public viewholder setimagebitmap(int viewid,bitmap bitmap){ imageview iv = getview(viewid); iv.setimagebitmap(bitmap); return this; } }
searchview.java
package com.bzu.gxs.search.widget; import android.app.activity; import android.content.context; import android.text.editable; import android.text.textwatcher; import android.util.attributeset; import android.view.keyevent; import android.view.layoutinflater; import android.view.view; import android.view.inputmethod.editorinfo; import android.view.inputmethod.inputmethodmanager; import android.widget.adapterview; import android.widget.arrayadapter; import android.widget.button; import android.widget.edittext; import android.widget.imageview; import android.widget.linearlayout; import android.widget.listview; import android.widget.textview; import com.bzu.gxs.search.r; public class searchview extends linearlayout implements view.onclicklistener { /** * 输入框 */ private edittext etinput; /** * 删除键 */ private imageview ivdelete; /** * 返回按钮 */ private button btnback; /** * 上下文对象 */ private context mcontext; /** * 弹出列表 */ private listview lvtips; /** * 提示adapter (推荐adapter) */ private arrayadapter<string> mhintadapter; /** * 自动补全adapter 只显示名字 */ private arrayadapter<string> mautocompleteadapter; /** * 搜索回调接口 */ private searchviewlistener mlistener; /** * 设置搜索回调接口 * * @param listener 监听者 */ public void setsearchviewlistener(searchviewlistener listener) { mlistener = listener; } public searchview(context context, attributeset attrs) { super(context, attrs); mcontext = context; layoutinflater.from(context).inflate(r.layout.activity_search, this); initviews(); } private void initviews() { etinput = (edittext) findviewbyid(r.id.search_et_input); ivdelete = (imageview) findviewbyid(r.id.search_iv_delete); btnback = (button) findviewbyid(r.id.search_btn_back); lvtips = (listview) findviewbyid(r.id.search_lv_tips); lvtips.setonitemclicklistener(new adapterview.onitemclicklistener() { @override public void onitemclick(adapterview<?> adapterview, view view, int i, long l) { //set edit text string text = lvtips.getadapter().getitem(i).tostring(); etinput.settext(text); etinput.setselection(text.length()); //hint list view gone and result list view show lvtips.setvisibility(view.gone); notifystartsearching(text); } }); ivdelete.setonclicklistener(this); btnback.setonclicklistener(this); etinput.addtextchangedlistener(new editchangedlistener()); etinput.setonclicklistener(this); etinput.setoneditoractionlistener(new textview.oneditoractionlistener() { @override public boolean oneditoraction(textview textview, int actionid, keyevent keyevent) { if (actionid == editorinfo.ime_action_search) { lvtips.setvisibility(gone); notifystartsearching(etinput.gettext().tostring()); } return true; } }); } /** * 通知监听者 进行搜索操作 * @param text */ private void notifystartsearching(string text){ if (mlistener != null) { mlistener.onsearch(etinput.gettext().tostring()); } //隐藏软键盘 inputmethodmanager imm = (inputmethodmanager) mcontext.getsystemservice(context.input_method_service); imm.togglesoftinput(0, inputmethodmanager.hide_not_always); } /** * 设置热搜版提示 adapter */ public void settipshintadapter(arrayadapter<string> adapter) { this.mhintadapter = adapter; if (lvtips.getadapter() == null) { lvtips.setadapter(mhintadapter); } } /** * 设置自动补全adapter */ public void setautocompleteadapter(arrayadapter<string> adapter) { this.mautocompleteadapter = adapter; } private class editchangedlistener implements textwatcher { @override public void beforetextchanged(charsequence charsequence, int i, int i2, int i3) { } @override public void ontextchanged(charsequence charsequence, int i, int i2, int i3) { if (!"".equals(charsequence.tostring())) { ivdelete.setvisibility(visible); lvtips.setvisibility(visible); if (mautocompleteadapter != null && lvtips.getadapter() != mautocompleteadapter) { lvtips.setadapter(mautocompleteadapter); } //更新autocomplete数据 if (mlistener != null) { mlistener.onrefreshautocomplete(charsequence + ""); } } else { ivdelete.setvisibility(gone); if (mhintadapter != null) { lvtips.setadapter(mhintadapter); } lvtips.setvisibility(gone); } } @override public void aftertextchanged(editable editable) { } } @override public void onclick(view view) { switch (view.getid()) { case r.id.search_et_input: lvtips.setvisibility(visible); break; case r.id.search_iv_delete: etinput.settext(""); ivdelete.setvisibility(gone); break; case r.id.search_btn_back: ((activity) mcontext).finish(); break; } } /** * search view回调方法 */ public interface searchviewlistener { /** * 更新自动补全内容 * * @param text 传入补全后的文本 */ void onrefreshautocomplete(string text); /** * 开始搜索 * * @param text 传入输入框的文本 */ void onsearch(string text); } }
布局文件:
activity_main.xml
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#ffffff" tools:context=".activity.searchactivity" android:orientation="vertical"> <com.bzu.gxs.search.widget.searchview android:id="@+id/main_search_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:fitssystemwindows="true"> </com.bzu.gxs.search.widget.searchview> <listview android:id="@+id/main_lv_search_results" android:layout_width="match_parent" android:layout_height="wrap_content"> </listview> </linearlayout>
activity_search.xml
<?xml version="1.0" encoding="utf-8"?> <linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="#ffffff" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <linearlayout android:background="#e5e5e5" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <framelayout android:layout_weight="1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical"> <edittext android:id="@+id/search_et_input" android:layout_gravity="center_vertical" android:layout_margin="10dp" android:drawableleft="@drawable/ic_search" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@drawable/search_edittext_shape" android:textsize="16sp" android:imeoptions="actionsearch" android:inputtype="text" android:hint="请输入搜索的内容"/> <imageview android:visibility="gone" android:layout_marginright="20dp" android:src="@drawable/ic_delete" android:id="@+id/search_iv_delete" android:layout_gravity="right|center_vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </framelayout> <button android:id="@+id/search_btn_back" android:layout_marginright="10dp" android:paddingleft="5dp" android:paddingright="10dp" android:layout_gravity="center_vertical" android:text="取消" android:textcolor="#ea5421" android:textsize="15sp" android:background="@null" android:layout_height="wrap_content" android:layout_width="50dp" /> </linearlayout> <listview android:visibility="gone" android:id="@+id/search_lv_tips" android:background="#ffffff" android:layout_marginbottom="10dp" android:layout_width="match_parent" android:layout_height="600dp"> </listview> </linearlayout>
item_search.xml
<?xml version="1.0" encoding="utf-8"?> <relativelayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ffffff" android:layout_margin="10dp" android:layout_margintop="5dp"> <imageview android:src="@mipmap/ic_launcher" android:id="@+id/item_search_iv_icon" android:layout_marginleft="20dp" android:layout_centervertical="true" android:layout_width="60dp" android:layout_height="60dp"/> <textview android:id="@+id/item_search_tv_title" android:layout_margintop="15dp" android:layout_marginleft="10dp" android:layout_torightof="@id/item_search_iv_icon" android:text="title" android:textsize="15sp" android:textcolor="#000" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <textview android:id="@+id/item_search_tv_content" android:layout_marginleft="10dp" android:layout_marginbottom="10dp" android:layout_marginright="50dp" android:layout_torightof="@id/item_search_iv_icon" android:layout_below="@id/item_search_tv_title" android:text="content" android:textsize="14sp" android:textcolor="#777" android:layout_width="match_parent" android:layout_height="wrap_content"/> <textview android:id="@+id/item_search_tv_comments" android:layout_marginright="20dp" android:layout_alignparentright="true" android:layout_centervertical="true" android:text="title" android:singleline="true" android:textsize="14sp" android:textcolor="#777" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </relativelayout>
以上就是本文的全部内容,希望能给大家一个参考,也希望大家多多支持。
上一篇: Java面向对象选择题总结归纳