【发布时间】:2012-01-13 00:35:23
【问题描述】:
我一直在搜索很多关于通过编辑文本在列表视图中搜索项目的信息,尽管我发现了许多与我的问题类似的问题,但是在任何使用光标适配器的地方,直接从数据库中获取过滤结果或某个数组列表是用过。
就我而言,我一直在使用几个数组来使用基本适配器为我的列表视图传递文本。因为我以前从未做过这样的事情,所以我无法理解文本观察器的使用。
我调试了代码,发现没有调用发布结果方法,这可能是列表视图无法获取新值的原因。 我是否必须再次调用 listviewadaptercontacts 类,并在 text changed 方法中使用 names 数组中的刷新值。
请帮忙。
public class AllContactsActivity extends ListActivity implements
android.view.View.OnClickListener, OnItemClickListener {
ListView lv;
ListViewAdapterContacts lva;
String[] names, phones, ids, types;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LayoutParams params = new RelativeLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
LayoutInflater layoutInflater = getLayoutInflater();
mainLayout.addView(layoutInflater.inflate(R.layout.allcontacts, null));
mainLayout.addView(layoutInflater.inflate(R.layout.allbuttons, null));
this.addContentView(mainLayout, params);
configureBottomMenu();
getContacts();
lv = new ListView(getApplicationContext());
lv = (ListView) findViewById(android.R.id.list);
lva = new ListViewAdapterContacts(this, names, types, phones, ids); //passing arrays to class
lv.setAdapter(lva);
et = (EditText) findViewById(R.id.searchcontact);
et.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) { // TODO Auto-generated method stub
lva.getFilter().filter(s);
lva.notifyDataSetInvalidated();
lva.notifyDataSetChanged();
lv.setAdapter(lva);
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
//some code
}
}
public class ListViewAdapterContacts extends BaseAdapter implements Filterable {
private ArrayFilter mFilter;
private ArrayList < String > mOriginalValues;
private final Object mLock = new Object();
private List < String > mObjects;
List list;
Activity context;
String[] names;
String[] types;
String[] numbers;
String[] ids;
public ListViewAdapterContacts(Activity context, String[] names, String[] types, String[] numbers, String[] ids) {
// TODO Auto-generated constructor stub
this.context = context;
this.names = names;
this.types = types;
this.numbers = numbers;
this.ids = ids;
Object[] array = names;
list = Arrays.asList(array);
}
public int getCount() {
// TODO Auto-generated method stub
if (names == null) {
return 0;
} else {
return names.length;
}
}
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
public class viewHolder {
TextView top;
TextView bottom;
TextView downside;
TextView base;
}
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
viewHolder holder;
if (convertView == null) {
LayoutInflater inflator = context.getLayoutInflater();
convertView = inflator.inflate(R.layout.textviewonly, null);
holder = new viewHolder();
holder.top = (TextView) convertView.findViewById(R.id.toptext);
holder.bottom = (TextView) convertView.findViewById(R.id.bottomtext);
holder.downside = (TextView) convertView.findViewById(R.id.lowest);
holder.base = (TextView) convertView.findViewById(R.id.baseid);
convertView.setTag(holder);
} else {
holder = (viewHolder) convertView.getTag();
}
holder.top.setText(names[position]);
holder.bottom.setText(types[position]);
holder.downside.setText(numbers[position]);
holder.base.setText(ids[position]);
return convertView;
}
public Filter getFilter() {
// TODO Auto-generated method stub
if (mFilter == null) {
mFilter = new ArrayFilter();
}
return mFilter;
}
private class ArrayFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized(mLock) {
//mOriginalValues = new ArrayList<String>(mObjects);
mOriginalValues = new ArrayList < String > (list);
}
}
if (prefix == null || prefix.length() == 0) {
synchronized(mLock) {
ArrayList < String > list = new ArrayList < String > (mOriginalValues);
results.values = list;
results.count = list.size();
}
} else {
String prefixString = prefix.toString().toLowerCase();
final ArrayList < String > values = mOriginalValues;
final int count = values.size();
final ArrayList < String > newValues = new ArrayList < String > (count);
for (int i = 0; i < count; i++) {
final String value = values.get(i);
final String valueText = value.toString().toLowerCase();
// First match against the whole, non-splitted value
if (valueText.startsWith(prefixString)) {
newValues.add(value);
} else {
final String[] words = valueText.split(" ");
final int wordCount = words.length;
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);
break;
}
}
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
//noinspection unchecked
mObjects = (List < String > ) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
【问题讨论】:
-
为什么不创建一个实体类 Contract 并使用 List
而不是使用 String[] 名称、电话、ids、类型,这样更容易过滤数据。 -
但重点仍然相同。即使我使用实体类如何进行过滤
-
迭代List
,检查是否有合约满足contract.name.equals(NAME)等条件,将符合条件的放入一个新的List中,然后将新的List放入Adapter的构造函数 -
这意味着我必须遍历列表中的每个元素。如果我有 200 个联系人怎么办,我认为在这种情况下,对于编辑文本的每个字符,过滤器方法将查找该字符串/我的联系人列表中的角色。你不认为它会影响演出吗?
-
如果有200个联系人,我认为不会影响性能,反正你可以试一试。
标签: android listview filtering baseadapter