校验:
我想实现我的过滤器ListView
。 但我面临一个很奇怪的一种问题。 如果键入字母T
的EditText
的ListView
是越来越充满了从开始的姓名B
, J
。 请帮忙。
public class MyCustomAdapter extends BaseAdapter implements Filterable {
Context mContext;
private LayoutInflater mInflater;
SparseBooleanArray mSparseBooleanArray;
private ArrayList<Map<String,String>> mAdapData = new ArrayList<Map<String, String>>();
private ArrayList<Map<String,String>> mOriginalData = new ArrayList<Map<String, String>>();
public MyCustomAdapter(Context mContext) {
mInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSparseBooleanArray = new SparseBooleanArray();
}
public ArrayList<String> getCheckedItems() {
ArrayList<String> mTempArry = new ArrayList<String>();
for (int i = 0; i < mAdapData.size(); i++) {
if (mSparseBooleanArray.get(i)) {
Map<String, String> map = (Map<String, String>) mAdapData.get(i);
final String numbr = map.get("Phone").toString();
mTempArry.add(numbr);
}
}
return mTempArry;
}
@Override
public int getCount() {
return this.mAdapData.size();
}
public void addItem(String paramString1, String paramString2) {
Map<String, String> NameNumber = new HashMap<String, String>();
NameNumber.put("Name", paramString1);
NameNumber.put("Phone", paramString2);
this.mAdapData.add(NameNumber);
this.mOriginalData.add(NameNumber);
notifyDataSetChanged();
}
@SuppressWarnings("unchecked")
public Object getItem(int paramInt) {
return (ArrayList<Map<String, String>>) this.mAdapData.get(paramInt);
}
@Override
public long getItemId(int paramInt) {
return paramInt;
}
@Override
public View getView(final int paramInt, View paramView, ViewGroup paramViewGroup) {
ViewHolder viewHolder;
if (paramView == null) {
viewHolder = new ViewHolder();
paramView = mInflater.inflate(R.layout.multiplecontactview, null);
viewHolder.tvName = (TextView) paramView.findViewById(R.id.txtContactName);
viewHolder.tvNumber = (TextView) paramView.findViewById(R.id.txtContactNumber);
viewHolder.cb = (CheckBox) paramView.findViewById(R.id.checkBox1);
viewHolder.cb.setTag(paramInt);
viewHolder.cb.setChecked(mSparseBooleanArray.get(paramInt));
viewHolder.cb.setOnCheckedChangeListener(mCheckedChangeListener);
viewHolder.tvName.setTextColor(Color.BLACK);
viewHolder.tvNumber.setTextColor(Color.BLACK);
for (int i = 0; i < mAdapData.size(); i++) {
Map<String, String> map = (Map<String, String>) mAdapData.get(paramInt);
final String name = map.get("Name").toString();
Log.e("Name", name);
final String numbr = map.get("Phone").toString();
Log.e("Number", numbr);
viewHolder.tvName.setText(name);
viewHolder.tvNumber.setText(numbr);
}
paramView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) paramView.getTag();
}
return paramView;
}
OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mSparseBooleanArray.put((Integer) buttonView.getTag(), isChecked);
}
};
public static class ViewHolder {
TextView tvName;
TextView tvNumber;
CheckBox cb;
}
@Override
public Filter getFilter() {
return new MyContactFilter();
}
@SuppressLint("DefaultLocale")
private class MyContactFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<Map<String, String>> mFilteredData = new ArrayList<Map<String, String>>();
if (!TextUtils.isEmpty(constraint)) {
for(int i = 0; i < mAdapData.size(); i++) {
Map<String, String> map = (Map<String, String>) mAdapData.get(i);
final String names = map.get("Name").toString();
final String numbr = map.get("Phone").toString();
if(names.toLowerCase().contains(constraint.toString().toLowerCase())) {
Map<String, String> FilNameNumber = new HashMap<String, String>();
FilNameNumber.put("Name", names);
FilNameNumber.put("Phone", numbr);
mFilteredData.add(FilNameNumber);
}
}
results.values = mFilteredData;
results.count = mFilteredData.size();
} else {
synchronized (mOriginalData) {
results.values = mOriginalData;
results.count = mOriginalData.size();
}
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence cs, FilterResults fr) {
mAdapData = (ArrayList<Map<String, String>>) fr.values;
notifyDataSetChanged();
}
}
}
你的问题是来自你的方式设置的getView()
方法,以及如何在SparseBooleanArray设定的检查项目。 我已经编辑您的适配器的代码,它现在应该工作。 主要的变化是在OnCheckedChangeListener
领域:
public class MyCustomAdapter extends BaseAdapter implements Filterable {
private Context mContext;
private LayoutInflater mInflater;
private SparseBooleanArray mSparseBooleanArray;
// from where do you get the data?
private ArrayList<Map<String, String>> mAdapData = new ArrayList<Map<String, String>>();
private ArrayList<Map<String, String>> mOriginalData = new ArrayList<Map<String, String>>();
public MyCustomAdapter(Context mContext) {
mInflater = (LayoutInflater) mContext
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mSparseBooleanArray = new SparseBooleanArray();
}
public ArrayList<String> getCheckedItems() {
ArrayList<String> mTempArry = new ArrayList<String>();
for (int i = 0; i < mAdapData.size(); i++) {
if (mSparseBooleanArray.get(i)) {
Map<String, String> map = (Map<String, String>) mAdapData
.get(i);
final String numbr = map.get("Phone");
mTempArry.add(numbr);
}
}
return mTempArry;
}
@Override
public int getCount() {
return this.mAdapData.size();
}
public void addItem(String paramString1, String paramString2) {
Map<String, String> NameNumber = new HashMap<String, String>();
NameNumber.put("Name", paramString1);
NameNumber.put("Phone", paramString2);
mAdapData.add(NameNumber);
mOriginalData.add(NameNumber);
notifyDataSetChanged();
}
@SuppressWarnings("unchecked")
public Object getItem(int paramInt) {
return (ArrayList<Map<String, String>>) this.mAdapData.get(paramInt);
}
@Override
public long getItemId(int paramInt) {
return paramInt;
}
@Override
public View getView(final int paramInt, View paramView,
ViewGroup paramViewGroup) {
ViewHolder viewHolder;
if (paramView == null) {
viewHolder = new ViewHolder();
paramView = mInflater.inflate(R.layout.adapters_specialfilterrow,
paramViewGroup, false);
viewHolder.tvName = (TextView) paramView
.findViewById(R.id.textView1);
viewHolder.tvNumber = (TextView) paramView
.findViewById(R.id.textView2);
viewHolder.cb = (CheckBox) paramView.findViewById(R.id.checkBox1);
paramView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) paramView.getTag();
}
viewHolder.cb.setTag(paramInt);
viewHolder.cb.setOnCheckedChangeListener(null);
viewHolder.cb.setChecked(mSparseBooleanArray.get(paramInt));
viewHolder.cb.setOnCheckedChangeListener(mCheckedChangeListener);
viewHolder.tvName.setTextColor(Color.BLACK);
viewHolder.tvNumber.setTextColor(Color.BLACK);
Map<String, String> map = (Map<String, String>) mAdapData.get(paramInt);
final String name = map.get("Name");
final String numbr = map.get("Phone");
viewHolder.tvName.setText(name);
viewHolder.tvNumber.setText(numbr);
return paramView;
}
OnCheckedChangeListener mCheckedChangeListener = new OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
// get the item from the current mAdapData
Map<String, String> item = mAdapData.get((Integer) buttonView
.getTag());
int position = -1;
// see where is the item placed in the mOriginalData and use that
// position
for (int i = 0; i < mOriginalData.size(); i++) {
final Map<String, String> tmp = mOriginalData.get(i);
if (tmp.get("Name").toLowerCase().equals(item.get("Name").toLowerCase())) {
position = i;
break;
}
}
mSparseBooleanArray.put(position, isChecked);
}
};
public static class ViewHolder {
TextView tvName;
TextView tvNumber;
CheckBox cb;
}
@Override
public Filter getFilter() {
return new MyContactFilter();
}
@SuppressLint("DefaultLocale")
private class MyContactFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<Map<String, String>> mFilteredData = new ArrayList<Map<String, String>>();
if (!TextUtils.isEmpty(constraint)) {
for (int i = 0; i < mAdapData.size(); i++) {
Map<String, String> map = (Map<String, String>) mAdapData
.get(i);
final String names = map.get("Name");
final String numbr = map.get("Phone");
if (names.toLowerCase().contains(
constraint.toString().toLowerCase())) {
Map<String, String> FilNameNumber = new HashMap<String, String>();
FilNameNumber.put("Name", names);
FilNameNumber.put("Phone", numbr);
mFilteredData.add(FilNameNumber);
}
}
results.values = mFilteredData;
results.count = mFilteredData.size();
} else {
synchronized (mOriginalData) {
results.values = mOriginalData;
results.count = mOriginalData.size();
}
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence cs, FilterResults fr) {
mAdapData = (ArrayList<Map<String, String>>) fr.values;
notifyDataSetChanged();
}
}
}
我还实施过滤器列表查看我的应用程序。 对于这一点,我只是需要的代码片段。 检查它,如果它帮助。
editText.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
}
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
}
public void afterTextChanged(Editable arg0) {
sendToList.this.adapter.getFilter().filter(arg0);
}
});
在getView()
方法,你没有更新UI有过滤结果的值。 所以它返回旧的结果的看法。
之前返回paramView,视图的数据更新到您的筛选结果是什么,并从viewHolder的准备删除它,因为这是只叫了几声。
编辑:这是我的代码修正。 我认为这将解决这个问题:
@Override
public View getView(final int paramInt, View paramView, ViewGroup paramViewGroup) {
ViewHolder viewHolder;
if (paramView == null) {
viewHolder = new ViewHolder();
paramView = mInflater.inflate(R.layout.multiplecontactview, null);
viewHolder.tvName = (TextView) paramView.findViewById(R.id.txtContactName);
viewHolder.tvNumber = (TextView) paramView.findViewById(R.id.txtContactNumber);
viewHolder.cb = (CheckBox) paramView.findViewById(R.id.checkBox1);
viewHolder.tvName.setTextColor(Color.BLACK);
viewHolder.tvNumber.setTextColor(Color.BLACK);
paramView.setTag(viewHolder);
viewHolder.cb.setOnCheckedChangeListener(mCheckedChangeListener);
} else {
viewHolder = (ViewHolder) paramView.getTag();
}
viewHolder.cb.setTag(paramInt);
viewHolder.cb.setChecked(mSparseBooleanArray.get(paramInt));
Map<String, String> map = (Map<String, String>) mAdapData.get(paramInt);
final String name = map.get("Name").toString();
Log.e("Name", name);
final String numbr = map.get("Phone").toString();
Log.e("Number", numbr);
viewHolder.tvName.setText(name);
viewHolder.tvNumber.setText(numbr);
return paramView;
}
编辑:这是我如何处理过滤的示例:
@Override
public Filter getFilter()
{
final Filter filter=new Filter()
{
@Override
protected FilterResults performFiltering(final CharSequence constraint)
{
_lastFilterConstraint=constraint;
if(TextUtils.isEmpty(constraint))
return null;
final String constraintToCheck=constraint.toString().toLowerCase(Locale.getDefault());
final FilterResults results=new FilterResults();
// <- here i do the filtering itself and later put the results into "results"
results.values=values;
results.count=values.size();
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(final CharSequence constraint,final FilterResults results)
{
_filteredItems==null ? null : (ArrayList<Item>)results.values;
notifyDataSetChanged();
}
};
return filter;
}
@Override
public int getCount()
{
if(_filteredItems!=null)
return _filteredItems.size();
return _originalItems.size();
}
@Override
public Item getItem(final int position)
{
if(_filteredItems!=null)
{
if(position<_filteredItems.size())
return _filteredItems.get(position);
return null;
}
if(position<_originalItems.size())
return _originalItems.get(position);
return null;
}
@Override
public View getView(final int position,final View convertView,final ViewGroup parent)
{
final View inflatedView;
final ViewHolder viewHolder;
if(convertView==null)
{
//<- here i inflate the view into the inflatedView
}
else
{
inflaterView=convertView;
viewHolder=(ViewHolder)inflaterView.getTag();
}
// <- here i use getItem and update the view according to its data .
return inflaterView;
}