我已经坚持了几个小时,我的想法是在EditText的帮助下有一个可过滤的列表。为此,我使用StickyListHeadersListView和可过滤的StickyListHeadersAdapter。这是我目前的代码:
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);
}
}
现在一切都显示得很好我打电话给 updateUsersList 列表函数调用 notifyDataSetChanged 并且它工作正常,我可以看到所有列表中的部分。
然后在使用EditText时,输入字母 B ,例如过滤器类返回2个过滤的项目,然后我将这2个项目的列表传递给< em> notifyFilterDataSetChanged 函数,以便粘性列表仅显示2个项目。此时它失败了,整个列表保持不变。我可能在这一点上失踪了,我一直在阅读所有好的建议但是徒劳无功。有什么想法吗?
答案 0 :(得分:0)
首先,你有一个错误的getItemId实现。如果你使用hasStableIds(true),你不应该依赖于位置。尝试使它像
@Override
public long getItemId(int position) {
return getItem(position).getId();
}
我想你的User类中有某种id,不是吗?
其次,你在UI线程中调用publishResults吗?尝试使其运行runOnUhThread()或listView.post()来检查一切是否正确。
第三,你有几个适配器初始化?检查您是否将事件传递给正确的事件(绑定到列表视图的事件)。