可过滤StickyListHeadersAdapter,notifyDataSetChanged不工作
问题描述:
我一直坚持了几个小时,这个想法是有一个可编辑列表帮助EditText。为此,我使用可过滤StickyListHeadersAdapter的StickyListHeadersListView。这里是我当前的代码:可过滤StickyListHeadersAdapter,notifyDataSetChanged不工作
public class PersonaFilterAdapter extends BaseAdapter implements StickyListHeadersAdapter, Filterable {
private int mResource;
private List<User> mUserList = new ArrayList<>();
private Set<User> mUserHashSet;
/** Filter parameters **/
private ArrayList<User> mFilteredObjects = new ArrayList<>();
private Filter mFilter;
public PersonaFilterAdapter(int resource, List<User> objects, Set<User> userHashSet) {
this.mResource = resource;
this.mUserList.addAll(objects);
this.mFilteredObjects.addAll(objects);
this.mUserHashSet = userHashSet;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = LayoutInflater.from(parent.getContext()).inflate(mResource, parent, false);
holder = new ViewHolder();
holder.avatar = (SimpleDraweeView) convertView.findViewById(R.id.userAvatar);
holder.name = (TextView) convertView.findViewById(R.id.userName);
holder.position = (TextView) convertView.findViewById(R.id.userPosition);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
User user = getItem(position);
int size = 100;
String imgString = SlingCloudinary.getInstance().getAvatar(user, size, size);
Uri uri = Uri.parse(imgString);
holder.avatar.setImageURI(uri);
holder.name.setText(String.format("%s %s", user.getName(), user.getLastname()));
holder.position.setText(user.getDescription());
if (mUserHashSet != null) {
ListView listView = (ListView) parent;
if (mUserHashSet.contains(user)) {
listView.setItemChecked(position, true);
} else {
listView.setItemChecked(position, false);
}
}
return convertView;
}
public void updateUsersList(List<User> userList) {
mUserList.clear();
mUserList.addAll(userList);
mFilteredObjects.clear();
mFilteredObjects.addAll(mUserList);
this.notifyDataSetChanged();
}
public void notifyFilterDataSetChanged(List<User> userList) {
mFilteredObjects.clear();
mFilteredObjects.addAll(userList);
notifyDataSetChanged();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public User getItem(int position) {
return mFilteredObjects.get(position);
}
@Override
public int getCount() {
return mFilteredObjects.size();
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new AppFilter();
}
return mFilter;
}
class ViewHolder {
SimpleDraweeView avatar;
TextView name;
TextView position;
}
class HeaderViewHolder {
TextView text;
}
@Override
public View getHeaderView(int position, View convertView, ViewGroup parent) {
HeaderViewHolder holder;
if (convertView == null) {
holder = new HeaderViewHolder();
convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.header_section_persona, parent, false);
holder.text = (TextView) convertView.findViewById(R.id.personaSectionText);
convertView.setTag(holder);
} else {
holder = (HeaderViewHolder) convertView.getTag();
}
// set header text as first char in name
CharSequence headerChar = getItem(position).getName().subSequence(0, 1);
holder.text.setText(headerChar);
return convertView;
}
@Override
public long getHeaderId(int position) {
return getItem(position).getName().subSequence(0,1).charAt(0);
}
@Override
public boolean hasStableIds() {
return true;
}
private class AppFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence chars) {
FilterResults result = new FilterResults();
if (chars != null && chars.length() > 0) {
String mask = chars.toString();
ArrayList<User> userList = new ArrayList<>();
for (User user : mUserList) {
if (keepObject(user, mask)) {
userList.add(user);
}
}
result.count = userList.size();
result.values = userList;
} else {
// add all objects
result.values = mUserList;
result.count = mUserList.size();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.count > 0) {
notifyFilterDataSetChanged((List<User>) results.values);
} else {
notifyDataSetInvalidated();
}
}
}
private boolean keepObject(User user, String mask) {
mask = mask.toLowerCase();
return user.getName().toLowerCase().startsWith(mask);
}
}
现在一切都在第一次显示好,我叫这就要求notifyDataSetChanged和正常工作的updateUsersList列表功能,我可以看到所有章节的列表。
之后使用的EditText时,通过键入字母乙例如在筛选类返回我2个过滤项目,我再通的2项的这个名单notifyFilterDataSetChanged功能,使粘列表仅显示2项。在这一点上它失败了,整个列表仍然是一样的。我可能在这一点上失踪,我一直在阅读所有好的建议,但徒劳无功。任何想法?
答
首先,你有一个错误的getItemId实现。如果你使用hasStableIds(true),你不应该依赖位置。尝试使它像
@Override
public long getItemId(int position) {
return getItem(position).getId();
}
我想你在你的用户类中有某种类型的ID,不是吗?
其次,你是否在UI线程中调用publishResults?尝试使runOnUiThread()或listView.post()检查一切是否正确。
三,你有几个适配器初始化?检查是否将事件传递给正确的事件(绑定到列表视图的事件)。
这是你提到的一个好点,我用这个hasStableIds而不知道它做了什么。即使设置为false,这仍然不起作用。我也尝试runOnUIThread和listView.post(),仍然不幸运.. –
除了你的实现似乎对我来说很正常。让我澄清一下 - 即使您的过滤的实现返回正确的结果(提供正确大小的过滤列表等)并通过notifyFilterDataSetChanged通知适配器,该列表仅显示初始值(未过滤的列表)?可能你有几个适配器初始化并将事件传递给错误的?你可以在传递OnTextChanged事件之前和之后检查适配器大小,但直接像listView.getAdapter()。getCount()那样检查它吗? – aelimill
并返回hasStableIds为true,只是实现正常的逻辑getItemId() – aelimill