SearchView的简略用法
SearchView的简单用法
SearchView是在api 11后出现的,用它来做搜索功能,可以监听字符串变化事件和按钮点击事件
1.创建SearchView对象,和其他控件一样使用,xml文件如下:
file_search_activity.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <ListView android:id="@+id/lv_file_search_infor" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@+id/layout_file_search_top" android:layout_marginLeft="10dip" android:layout_marginRight="10dip" android:layout_above="@+id/layout_file_saerch_bottom" ></ListView> <SearchView android:id="@+id/sv_file_search_name" android:layout_width="fill_parent" android:layout_height="50dip" android:background="@drawable/shape_edit" android:inputType="textFilter" android:queryHint="@string/please_input_name" android:iconifiedByDefault="true" android:imeOptions="actionSearch" /> </LinearLayout>java文件:
FileSearchActivity.java
/* * @Project: SlideMenuFragment * @User: Android * @Description: neldtv手机云相册第二版本 * @Author: yan.yu * @Company:http://www.neldtv.org/ * @Date 2014-3-6 下午3:31:40 * @Version V2.0 */ package com.example.fragmenttest.fragment; import java.util.ArrayList; import java.util.List; import android.app.Activity; import android.app.SearchManager; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton; import android.widget.ListView; import android.widget.ProgressBar; import android.widget.SearchView; import android.widget.SearchView.OnQueryTextListener; import android.widget.TextView; import com.example.fragmenttest.R; import com.yyu.utils.MyFileInfor; import com.yyu.utils.MyFileUtil; import com.yyu.utils.MyStringUtil; import com.yyu.utils.MyViewUtil; import com.yyu.view.FileAdapter; /** * @ClassName: FileSearchFragment * @Description: TODO * @author yan.yu * @date 2014-3-6 下午3:31:40 */ public class FileSearchActivity extends Activity implements OnClickListener, OnQueryTextListener { private ListView lvSearch = null; private SearchView searchView = null; private FileAdapter adapter = null; private ArrayList<MyFileInfor> list = new ArrayList<MyFileInfor>(); private String dirPath = null; private final int MSG_GET_FILE_START = 0; private final int MSG_GET_FILE_FINISH = 1; Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if(msg.what == MSG_GET_FILE_START) { } else if(msg.what == MSG_GET_FILE_FINISH) { List<MyFileInfor> tempList = (List<MyFileInfor>)msg.obj; list.clear(); list.addAll(tempList); tempList.clear(); adapter.notifyDataSetChanged(); } }; }; /** *callbacks */ @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.file_search_activity); lvSearch = (ListView)findViewById(R.id.lv_file_search_infor); searchView = (SearchView)findViewById(R.id.sv_file_search_name); lvSearch.setTextFilterEnabled(true);//设置对字符串过滤,对应的适配器要实现Filterable接口 searchView.setOnQueryTextListener(this);//监听输入框字符串变化 searchView.setSubmitButtonEnabled(true);//显示查询提交按钮 dirPath = getIntent().getStringExtra("dir_path"); adapter = new FileAdapter(getApplicationContext(), list); lvSearch.setAdapter(adapter); getFileList(dirPath); } private void getFileList(final String dirPath) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub MyViewUtil.sendMessage(handler, MSG_GET_FILE_START); List<MyFileInfor> tempList = MyFileUtil.getLocalFiles(getApplicationContext(), dirPath); MyViewUtil.sendMessage(handler, MSG_GET_FILE_FINISH, tempList); } }).start(); } /** *callbacks */ @Override public boolean onQueryTextChange(String newText) { // TODO Auto-generated method stub if (MyStringUtil.isEmpty(newText)) { // Clear the text filter. lvSearch.clearTextFilter(); } else { adapter.setCurPath(dirPath); // Sets the initial value for the text filter. //lvSearch.setFilterText(newText.toString());//字符串变化时直接查询 } return false; } /** *callbacks */ @Override public boolean onQueryTextSubmit(String arg0) { // TODO Auto-generated method stub lvSearch.setFilterText(arg0.trim());
return false; } } 2.创建适配器,实现Filterable接口
FileAdapter.java
/* * @Project: SlideMenuFragment * @User: Android * @Description: neldtv手机云相册第二版本 * @Author: yan.yu * @Company:http://www.neldtv.org/ * @Date 2014-3-6 下午4:15:20 * @Version V2.0 */ package com.yyu.view; import java.io.File; import java.util.ArrayList; import java.util.List; import android.content.Context; import android.graphics.Color; import android.os.Handler; import android.text.Spannable; import android.text.SpannableStringBuilder; import android.text.style.ForegroundColorSpan; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.CheckBox; import android.widget.Filter; import android.widget.Filterable; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.TextView; import com.example.fragmenttest.R; import com.yyu.common.Setting; import com.yyu.entity.FileType; import com.yyu.entity.Global; import com.yyu.utils.MyFileInfor; import com.yyu.utils.MyFileUtil; import com.yyu.utils.MyLog; import com.yyu.utils.MyStringUtil; import com.yyu.utils.MyViewUtil; /** * @ClassName: FileAdapter * @Description: TODO * @author yan.yu * @date 2014-3-6 下午4:15:20 */ public class FileAdapter extends BaseAdapter implements Filterable { private AdapterViewHolder vh = null; private LayoutInflater mInflater = null; private ArrayList<MyFileInfor> list = null; private ArrayList<MyFileInfor> allFileList = new ArrayList<MyFileInfor>(); private ArrayList<MyFileInfor> resultList = new ArrayList<MyFileInfor>(); private Context context = null; private boolean isSearch = false; private boolean isEdit = false; private String curPath = null; public FileAdapter(Context context, ArrayList<MyFileInfor> list) { mInflater = LayoutInflater.from(context); this.list = list; this.context = context; } public void notifyDataSetChanged(boolean isEdit) { this.isEdit = isEdit; notifyDataSetChanged(); } public void setCurPath(String curPath) { this.curPath = curPath; } /** *callbacks */ @Override public int getCount() { // TODO Auto-generated method stub if(isSearch) return resultList.size(); return list.size(); } /** *callbacks */ @Override public Object getItem(int arg0) { // TODO Auto-generated method stub if(isSearch) return resultList.get(arg0); return list.get(arg0); } /** *callbacks */ @Override public long getItemId(int arg0) { // TODO Auto-generated method stub return arg0; } /** *callbacks */ @Override public View getView(int position, View convertView, ViewGroup arg2) { // TODO Auto-generated method stub if(convertView == null) { vh = new AdapterViewHolder(); convertView = mInflater.inflate(R.layout.file_infor_fragment_item, null); vh.imageView = (ImageView)convertView.findViewById(R.id.iv_file_infor_fragment_item_type); vh.tvName = (TextView)convertView.findViewById(R.id.tv_file_infor_fragment_item_name); vh.tvInfor = (TextView)convertView.findViewById(R.id.tv_file_infor_fragment_item_infor); vh.checkBox = (CheckBox)convertView.findViewById(R.id.cb_file_infor_fragment_item); convertView.setTag(vh); } else vh = (AdapterViewHolder)convertView.getTag(); MyFileInfor fileInfor = null; if(isSearch) fileInfor = resultList.get(position); else fileInfor = list.get(position); if(isSearch) vh.tvName.setText(getStyle(fileInfor.getFileName(), fileInfor.getStyleIndex()[0], fileInfor.getStyleIndex()[1])); else vh.tvName.setText(fileInfor.getFileName()); if(isEdit) { vh.checkBox.setVisibility(View.VISIBLE); vh.checkBox.setChecked(fileInfor.isChecked()); MyViewUtil.setViewSelcted(convertView, vh.checkBox.isChecked()); } else { vh.checkBox.setVisibility(View.GONE); MyViewUtil.setViewSelcted(convertView, false); fileInfor.setIsChecked(false); } String dirInfor = null; if(fileInfor.isFolder())//文件夹 { if(!fileInfor.isLoaded()) dirInfor = context.getString(R.string.common_data_loading); else dirInfor = context.getString(R.string.local_file) + fileInfor.getSubFileCount() + ", " + context.getString(R.string.local_folder) + fileInfor.getSubDirCount(); } else { if(!fileInfor.isLoaded()) dirInfor = context.getString(R.string.common_data_loading); else { String size = MyStringUtil.getFormatSize(fileInfor.getFileSize()); String date = MyStringUtil.getFormatTime(fileInfor.getModifyTime()); dirInfor = date + " " + size; } } vh.tvInfor.setText(dirInfor); setIcon(vh, fileInfor, position); if(!fileInfor.isLoaded()) updateFileInfor(vh, fileInfor); return convertView; } private SpannableStringBuilder getStyle(String str, int start, int end) { if(start < 0) start = 0; if(end < 0) end = 0; SpannableStringBuilder style = new SpannableStringBuilder(str); style.setSpan(new ForegroundColorSpan(Color.RED), start, end, Spannable.SPAN_EXCLUSIVE_INCLUSIVE); return style; } private void setIcon(AdapterViewHolder vh, MyFileInfor fileInfor, int pos) { int type = fileInfor.getFileType(); boolean isThumbal = Setting.isThumbal(context); if(type == FileType.TYPE_FOLDER) { vh.imageView.setImageResource(R.drawable.file_folder); } else if(type == FileType.TYPE_IMAGE) { if(isThumbal) { Global.imageWorker.loadBitmap(fileInfor.getFileUrl(), new MyImageView(vh.imageView), 0); /*Bitmap tempBm = MyBitmapUtil.getImageThumbnail(fileInfor.getFileUrl(), 60, 60); if(tempBm != null && !tempBm.isRecycled()) vh.imageView.setImageBitmap(tempBm);*/ } else vh.imageView.setImageResource(R.drawable.file_image); } else if(type == FileType.TYPE_AUDIO) { vh.imageView.setImageResource(R.drawable.file_music); } else if(type == FileType.TYPE_VIDEO) { if(isThumbal) { Global.imageWorker.loadBitmap(fileInfor.getFileUrl(), new MyImageView(vh.imageView), 1); /*Bitmap tempBm = MyBitmapUtil.getVideoThumbnail(fileInfor.getFileUrl(), 60, 60, Thumbnails.MICRO_KIND); if(tempBm != null && !tempBm.isRecycled()) vh.imageView.setImageBitmap(tempBm);*/ } else vh.imageView.setImageResource(R.drawable.file_video); } else if(type == FileType.TYPE_ZIP) { vh.imageView.setImageResource(R.drawable.file_zip); } else if(type == FileType.TYPE_APK) { vh.imageView.setImageResource(R.drawable.ic_launcher); vh.imageView.setImageDrawable(MyFileUtil.getApkIcon(context, fileInfor.getFileUrl())); } else { vh.imageView.setImageResource(R.drawable.file_txt); } } private void updateFileInfor(final AdapterViewHolder vh, final MyFileInfor fileInfor) { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub if(fileInfor.isFolder())//文件夹 { List<MyFileInfor> tempList = MyFileUtil.getLocalFiles(context, fileInfor.getFileUrl()); int size = tempList.size(); int dirCount = 0; int fileCount = 0; for(int i=0;i<size;i++) { MyFileInfor infor = tempList.get(i); if(infor.isFolder()) dirCount ++; else fileCount ++; } fileInfor.setSubDirCount(dirCount); fileInfor.setSubFileCount(fileCount); } else { File tempFile = new File(fileInfor.getFileUrl()); fileInfor.setFileSize(tempFile.length());//文件大小 long time = tempFile.lastModified(); fileInfor.setModifyTime(time);//文件修改时间 } fileInfor.setIsLoad(true); MyViewUtil.sendMessage(handler, MSG_UPDATE_UI, fileInfor); } }).start(); } public class AdapterViewHolder { public ImageView imageView = null; public TextView tvName = null; public TextView tvInfor = null; public CheckBox checkBox = null; } private final int MSG_SEARCH_START = 0; private final int MSG_SEARCH_FINISH = 1; private final int MSG_SEARCH_RESET = 2; private final int MSG_UPDATE_UI = 3; Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { if(msg.what == MSG_SEARCH_START) { } else if(msg.what == MSG_SEARCH_FINISH) { int result = (Integer)msg.obj; } else if(msg.what == MSG_SEARCH_RESET) { } else if(msg.what == MSG_UPDATE_UI) { notifyDataSetChanged(); } }; }; /** *callbacks */ @Override public Filter getFilter() { // TODO Auto-generated method stub Filter filter = new Filter() { @Override protected void publishResults(CharSequence constraint, FilterResults results) { // TODO Auto-generated method stub if(isSearch) { List<MyFileInfor> tempList = (List<MyFileInfor>)results.values; if(tempList != null) { resultList.clear(); resultList.addAll(tempList); } } notifyDataSetChanged(); } @Override protected FilterResults performFiltering(CharSequence constraint) { // TODO Auto-generated method stub MyViewUtil.sendMessage(handler, MSG_SEARCH_START); FilterResults results = new FilterResults(); if (constraint!= null && constraint.toString().length() > 0) { ArrayList<MyFileInfor> resultList = new ArrayList<MyFileInfor>(); allFileList.clear(); MyFileUtil.getLocalFiles(allFileList, -1, curPath);//获取全部文件列表 int size = allFileList.size(); for (int index = 0; index < size; index++) { MyFileInfor fileInfor = allFileList.get(index); String si = fileInfor.getFileName(); String desStr = constraint.toString().toLowerCase(); String orgString = si.toLowerCase(); if(orgString.contains(desStr)) { int[] styleIndex = new int[2]; styleIndex[0] = orgString.indexOf(desStr); styleIndex[1] = styleIndex[0] + desStr.length(); fileInfor.setStyleIndex(styleIndex); resultList.add(fileInfor); } } results.values = resultList; results.count = resultList.size(); isSearch = true; MyViewUtil.sendMessage(handler, MSG_SEARCH_FINISH, resultList.size()); } else { isSearch = false; MyViewUtil.sendMessage(handler, MSG_SEARCH_RESET); synchronized (list) { results.values = list; results.count = list.size(); } } return results; } }; return filter; } }
在适配器中做字符串过滤,当执行lvSearch.setFilterText时触发getFilter中的performFiltering方法开始数据匹配
这里是直接回调onQueryTextSubmit监听按钮的,另外一种方法见:
http://blog.****.net/sun_star1chen/article/details/17140399