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.csdn.net/sun_star1chen/article/details/17140399