在我的应用中,我从网络服务器获取数据并在列表视图中显示数据。列表视图的适配器包含图像和文本。现在,我想过滤列表视图。为此,我在自定义适配器中实现了Filterable接口。但是,它没有给出任何结果。我搜索了很多,但没有得到任何结果。这是我的代码:
MainActivity
Runnable r = new Runnable()
{
@Override
public void run()
{
listMainMenu.setAdapter(mMenuAdapter);
listMainMenu.setTextFilterEnabled(true);
mMenuAdapter.notifyDataSetChanged();
pd.dismiss();
updateUI = false;
}//run
};
Text Watcher课程
_txtAutoSearch.addTextChangedListener(filterTextWatcher);
private TextWatcher filterTextWatcher = new TextWatcher() {
public void afterTextChanged(Editable s) {
Log.v(TAG+" filtertextwatcher", "afterTextChanged");
}//afterTextChanged
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.v(TAG+" filtertextwatcher", "beforeTextChanged");
}//beforeTextChanged
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.v(TAG+" filtertextwatcher", "onTextChanged");
((Filterable) listMainMenu.getAdapter()).getFilter().filter(s.toString());
}//onTextChanged
};
我的自定义适配器:
public class MainMenuAdapter extends BaseAdapter implements Filterable {
Context ctx;
ArrayList<MainCategoryDAO> mainCatDAOList;
public static final String TAG = "MainMenuAdapter";
ArrayList<MainCategoryDAO> arrayList;
public MainMenuAdapter(Context ctx, ArrayList<MainCategoryDAO> mainCatDAOList) {
this.ctx = ctx;
this.mainCatDAOList = mainCatDAOList;
}//Constructor
public int getCount() {
return mainCatDAOList.size();
}//getCount
public Object getItem(int position) {
return mainCatDAOList.get(position);
}//getItem
public long getItemId(int position) {
return 0;
}//getItemId
class ViewHolder {
ImageView imgCategoryIcon;
TextView txtCategoryName;
}//ViewHolder
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.main_menu_adapter, null);
holder = new ViewHolder();
holder.imgCategoryIcon = (ImageView)convertView.findViewById(R.id.imgCategoryIcon);
holder.txtCategoryName = (TextView)convertView.findViewById(R.id.txtCategoryName);
convertView.setTag(holder);
}//if
else {
holder = (ViewHolder) convertView.getTag();
}//else
Typeface cat_nameTF = Typeface.createFromAsset(ctx.getAssets(), "fonts/arial.ttf");
Log.v(TAG, "category name "+ mainCatDAOList.get(position).getCategory_name());
Log.v(TAG, "category icon "+ mainCatDAOList.get(position).getCategory_icon());
BitmapManager.INSTANCE.loadBitmap(mainCatDAOList.get(position).getCategory_icon(), holder.imgCategoryIcon, 50, 50);
holder.txtCategoryName.setTypeface(cat_nameTF);
holder.txtCategoryName.setText(mainCatDAOList.get(position).getCategory_name());
Log.v(TAG, "text view category name "+ holder.txtCategoryName.getText());
return convertView;
}//getView
@Override
public Filter getFilter()
{
Filter mFilter = new Filter()
{
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
{
Log.v(TAG+" getFilter", "publishResults called");
arrayList = (ArrayList<MainCategoryDAO>) results.values;
Log.v(TAG+" getFilter", "publishResults arrayList size "+arrayList.size());
for(int i = 0; i < arrayList.size(); i++)
{
Log.v(TAG+" getFilter filtered name", " "+arrayList.get(i).getCategory_name());
}//for
notifyDataSetChanged();
}//publishResults
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
Log.v(TAG+" getFilter", "performFiltering called");
FilterResults results = new FilterResults();
ArrayList<MainCategoryDAO> FilteredArrList = new ArrayList<MainCategoryDAO>();
if (constraint == null || constraint.length() == 0)
{
Log.v(TAG+" getFilter", "if, constraint.length null or 0");
results.count = mainCatDAOList.size();
results.values = mainCatDAOList;
}//if
else
{
Log.v(TAG+" getFilter", "else, constraint.length not 0");
constraint = constraint.toString();
Log.v(TAG+" getFilter", "else, constraint = "+constraint);
for (int i = 0; i < mainCatDAOList.size(); i++)
{
Log.v(TAG+" getFilter", "for loop, constraint.length not null or 0");
String data = mainCatDAOList.get(i).getCategory_name();
Log.v(TAG+" getFilter", "else, data to check "+data);
if (data.toLowerCase().startsWith(constraint.toString()))
{
Log.v(TAG+" getFilter", "if in for loop, constraint.length not null or 0");
FilteredArrList.add(mainCatDAOList.get(i));
}//if
}//for
results.count = FilteredArrList.size();
results.values = FilteredArrList;
}//else
return results;
}//performFiltering
};
return mFilter;
}//getFilter
}//MainMenuAdapter
经过测试,我发现它正在过滤结果,但更改并未反映在listview中。我甚至尝试将listview.setTextFilterEnabled()设置为true,但它也没有用。在我的logcat上,我可以看到过滤后的值。但没有理解为什么同样没有在UI中反映出来。
答案 0 :(得分:4)
您没有看到任何UI更改是正常的,因为您没有在过滤后更新正确的数据列表。您的MainMenuAdapter
基于mainCatDAOList
数据列表,但在publishResults
方法中,应该刷新适配器的数据:
arrayList = (ArrayList<MainCategoryDAO>) results.values;
notifyDataSetChanged();
正如您所看到的那样,您使用过滤后的值而不是arrayList
更新mainCatDAOList
,以便适配器看不到任何更改。所以你的代码应该是:
protected void publishResults(CharSequence constraint,
FilterResults results) {
Log.v(TAG+" getFilter", "publishResults called");
mainCatDAOList = (ArrayList<MainCategoryDAO>) results.values;
Log.v(TAG+" getFilter", "publishResults arrayList size "+arrayList.size());
for(int i = 0; i < arrayList.size(); i++)
{
Log.v(TAG+" getFilter filtered name", " "+arrayList.get(i).getCategory_name());
}//for
notifyDataSetChanged();
}
此外,您应该拥有要用于过滤的初始数据列表的副本,否则您将无法返回到完整的值集。
答案 1 :(得分:1)
你添加
Adapter.notifyDataSetChanged();
你的代码中的?你能展示你的主要活动代码吗?我会帮助我们。