我的代码有问题,我在适配器内搜索HashMap。它工作正常,但当我快速删除EditText中的所有字母,以便适配器显示键入的第一个完整字符串的列表,而不是所有元素的列表。
实施例: 我键入James,视图获取地图中的所有James,但是如果我快速删除EditText(按下后退),那么该方法会立即执行搜索并显示任何子字符串的正确列表(jame,jam,ja,j)但最后他再次显示列表继承了“詹姆斯”,而不是完整的联系人列表
感谢您的回答!
public class ContactsActivity extends ListActivity {
private HashMap<String, UserEntry> all_map_jid=new HashMap<String, UserEntry>();
private ArrayList<String> all_mkey=new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contacts);
getListView().setTextFilterEnabled(true);
final EditText searchText = (EditText) findViewById(R.id.searchbox);
TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//... your logic
adapter.getFilter().filter(s.toString());
}
@Override
public void afterTextChanged(Editable arg0) {
// ... your logic
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// ... your logic
}
};
searchText.addTextChangedListener(textWatcher);}
public class RosterAdapter extends BaseAdapter implements Filterable{
//private ViewHolder holder;
private LayoutInflater inflater;
private HashMap<String, UserEntry> mappa_users=null;
private ArrayList<String> mKeys;
public RosterAdapter(){
this.mappa_users =new HashMap<String, UserEntry>();
this.inflater= (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.mKeys=new ArrayList<String>();
}
@Override
public int getCount() {
return mappa_users.size();
}
@Override
public UserEntry getItem(int position) {
return mappa_users.get(mKeys.get(position));
}
@Override
public long getItemId(int arg0) {
return arg0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_row, null);
// Creates a ViewHolder and store references to the two children
// views we want to bind data to.
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.user_info);
holder.availability = (ImageView) convertView.findViewById(R.id.user_availability);
holder.user_ic = (ImageView) convertView.findViewById(R.id.icon);
// Keep track of the view holder as a tag of the view
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
String user = getItem(position).getUserName();
//Log.e("Nome","username "+user);
holder.username.setText(user);
if(!(getItem(position).getUserStatus())){
System.out.println("unavailable");
holder.availability.setImageResource(R.drawable.ic_not_available);
}else{
holder.availability.setImageResource(R.drawable.ic_available);
}
//do your view stuff here
return convertView;
}
@Override
public Filter getFilter() {
return new Filter() {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
mappa_users = (HashMap<String,UserEntry>) results.values;
mKeys= new ArrayList<String>(Arrays.asList(mappa_users.keySet().toArray(new String[mappa_users.size()])));
Collections.sort(mKeys, new RosterEntryComparator(mappa_users));
notifyDataSetChanged();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
HashMap<String,UserEntry> searched_user=new HashMap<String,UserEntry>();
FilterResults results = new FilterResults();
if (constraint!= null && constraint.toString().length() > 0) {
SmithWaterman metric = new SmithWaterman();
for(String element : all_mkey){
//La mappa dell'adapter è riempito con le sole entry simily all'occorrenza ricercata
if (metric.getSimilarity(constraint.toString().toLowerCase(), all_map_jid.get(element).getUserName().toLowerCase()) >= 0.8 ){
UserEntry rEntry=all_map_jid.get(element);
searched_user.put(element, rEntry );
}
}
results.values = searched_user;
results.count = searched_user.size();
}
else{
results.values = all_map_jid;
results.count = all_map_jid.size();
}
return results;
}
};
}
答案 0 :(得分:3)
<强>解决强>
我解决了这个问题,问题是我在任何新的输入上创建了一个新的Filter对象,使用相同的Filter一切正常,因为正如在android文档中写的那样:
public final void filter(CharSequence约束, Filter.FilterListener监听器)
在API级别1中添加启动异步筛选操作。 调用此方法会取消之前所有未执行的过滤 请求并发布将要执行的新过滤请求 后面。
这是正确的代码:
//My Adapter
public class RosterAdapter extends BaseAdapter implements Filterable{
//private ViewHolder holder;
private LayoutInflater inflater;
private ItemsFilter mFilter;
private HashMap<String, UserEntry> mappa_users=null;
private HashMap<String, UserEntry> all_map_jid=null;
private ArrayList<String> all_mkey=null;;
private ArrayList<String> mKeys;
public RosterAdapter(){
this.mappa_users =new HashMap<String, UserEntry>();
this.inflater= (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.all_map_jid=new HashMap<String, UserEntry>();
this.all_mkey=new ArrayList<String>();
this.mKeys=new ArrayList<String>();
}
@Override
public int getCount() {
return mappa_users.size();
}
@Override
public UserEntry getItem(int position) {
return mappa_users.get(mKeys.get(position));
}
@Override
public long getItemId(int arg0) {
return arg0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_row, null);
// Creates a ViewHolder and store references to the two children
// views we want to bind data to.
holder = new ViewHolder();
holder.username = (TextView) convertView.findViewById(R.id.user_info);
holder.availability = (ImageView) convertView.findViewById(R.id.user_availability);
holder.user_ic = (ImageView) convertView.findViewById(R.id.icon);
// Keep track of the view holder as a tag of the view
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
String user = getItem(position).getUserName();
//Log.e("Nome","username "+user);
holder.username.setText(user);
if(!(getItem(position).getUserStatus())){
holder.availability.setImageResource(R.drawable.ic_not_available);
}else{
holder.availability.setImageResource(R.drawable.ic_available);
}
//do your view stuff here
return convertView;
}
/**
* Implementing the Filterable interface.
*/
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ItemsFilter();
}
return mFilter;}
/**
* Custom Filter implementation for the items adapter.
*
*/
private class ItemsFilter extends Filter {
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.mappa_users = (HashMap<String,UserEntry>) results.values;
adapter.mKeys= new ArrayList<String>(Arrays.asList(adapter.mappa_users.keySet().toArray(new String[adapter.mappa_users.size()])));
Collections.sort(mKeys, new RosterEntryComparator(adapter.mappa_users));
notifyDataSetChanged();
Log.e("fine", "Terminato filtraggio "+constraint);
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
HashMap<String,UserEntry> searched_user=new HashMap<String,UserEntry>();
FilterResults results = new FilterResults();
if (constraint!= null && constraint.toString().length() > 0) {
SmithWaterman metric = new SmithWaterman();
for(String element : all_mkey){
//La mappa dell'adapter è riempito con le sole entry simily all'occorrenza ricercata
if (metric.getSimilarity(constraint.toString().toLowerCase(), all_map_jid.get(element).getUserName().toLowerCase()) >= 0.8 ){
UserEntry rEntry=all_map_jid.get(element);
searched_user.put(element, rEntry );
}
}
results.values = searched_user;
results.count = searched_user.size();
}
else{
results.values = all_map_jid;
results.count = all_map_jid.size();
}
return results;
}
};