2016-01-06 59 views
0

我一直堅持了幾個小時,這個想法是有一個可編輯列表幫助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項。在這一點上它失敗了,整個列表仍然是一樣的。我可能在這一點上失蹤,我一直在閱讀所有好的建議,但徒勞無功。任何想法?

回答

0

首先,你有一個錯誤的getItemId實現。如果你使用hasStableIds(true),你不應該依賴位置。嘗試使它像

@Override 
public long getItemId(int position) { 
    return getItem(position).getId(); 
} 

我想你在你的用戶類中有某種類型的ID,不是嗎?

其次,你是否在UI線程中調用publishResults?嘗試使runOnUiThread()或listView.post()檢查一切是否正確。

三,你有幾個適配器初始化?檢查是否將事件傳遞給正確的事件(綁定到列表視圖的事件)。

+0

這是你提到的一個好點,我用這個hasStableIds而不知道它做了什麼。即使設置爲false,這仍然不起作用。我也嘗試runOnUIThread和listView.post(),仍然不幸運.. –

+0

除了你的實現似乎對我來說很正常。讓我澄清一下 - 即使您的過濾的實現返回正確的結果(提供正確大小的過濾列表等)並通過notifyFilterDataSetChanged通知適配器,該列表僅顯示初始值(未過濾的列表)?可能你有幾個適配器初始化並將事件傳遞給錯誤的?你可以在傳遞OnTextChanged事件之前和之後檢查適配器大小,但直接像listView.getAdapter()。getCount()那樣檢查它嗎? – aelimill

+0

並返回hasStableIds爲true,只是實現正常的邏輯getItemId() – aelimill