2011-10-13 123 views
0

我試圖用自定義適配器過濾listview。當我開始在edittext上輸入時,應該過濾列表視圖。以下是適配器的代碼。自定義對象具有重寫方法toString,它返回Facebook用戶的名稱。我沒有重寫ArrayAdapter方法getItem,添加或刪除。ListView ArrayAdapter過濾 - 重複項目

public class FacebookFriendsAdapter extends ArrayAdapter<FacebookUser> { 
    private Activity activity; 
    public ImageLoader imageLoader; 
    private HashMap<String, Integer> alphaIndexer; 
    private String[] sections = new String[0]; 
    private boolean enableSections; 

    public FacebookFriendsAdapter(Context context, int textViewResourceId,ArrayList<FacebookUser> newItems) { 
     super(context, textViewResourceId, newItems); 
     imageLoader = new ImageLoader(context.getApplicationContext()); 
    } 

    public static class ViewHolder { 
     public TextView text; 
     public ImageView image; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View rowView = convertView; 
     FacebookUser fcbu = getItem(position); 

     if (convertView == null) { 
      LayoutInflater vi = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      rowView = vi.inflate(R.layout.facebook_friendslist_row, null); 
      final ViewHolder holder = new ViewHolder(); 
      holder.text = (TextView) rowView.findViewById(R.id.facebook_rowFriendName); 
      holder.image = (ImageView) rowView.findViewById(R.id.facebookRowUserFoto); 
      rowView.setTag(holder); 
     } else { 
      rowView = convertView; 
     } 
     ViewHolder holder = (ViewHolder) rowView.getTag(); 

     String imageurl = "http://graph.facebook.com/" + fcbu.getId()+ "/picture"; 
     holder.text.setText(fcbu.getName()); 
     holder.image.setTag(imageurl); 
     imageLoader.DisplayImage(imageurl, holder.image); 
     return rowView; 
    } 
} 

上的活動持有的EditText我創建了一個TextWatcher,如:

private TextWatcher filterTextWatcher = new TextWatcher() { 

     public void afterTextChanged(Editable s) { 

     } 

     public void beforeTextChanged(CharSequence s, int start, int count, 
       int after) { 
     } 

     public void onTextChanged(CharSequence s, int start, int before, 
       int count) { 
      facebookAdapter.getFilter().filter(s); 
     } 
    }; 

一切正常預期過濾列表後,經過濾項被複制。

如果有什麼可能導致這種情況,我將不勝感激。 謝謝

+0

通過重複,你的意思是每個2,每個隨機數,他們似乎重複,當你滾動......? –

+0

是的,每個都有2個。 – user738686

回答

4

我解決了這個問題歸功於How to write a custom filter for ListView with ArrayAdapter

下面是改編自定義適配器

public class FBAdapter extends ArrayAdapter<FacebookUser> { 
    public ImageLoader imageLoader; 
    private ArrayList<FacebookUser> items; 
    private ArrayList<FacebookUser> originalItems = new ArrayList<FacebookUser>(); 
    private FBAdapterFilter filter; 
    private final Object mLock = new Object(); 

    public FBAdapter(Context context, int textViewResourceId, 
      ArrayList<FacebookUser> newItems) { 
     super(context, textViewResourceId, newItems); 
     imageLoader = new ImageLoader(context); 
     items = newItems; 
     cloneItems(newItems); 
    } 

    protected void cloneItems(ArrayList<FacebookUser> items) { 
     for (Iterator iterator = items.iterator(); iterator.hasNext();) { 
      FacebookUser gi = (FacebookUser) iterator.next(); 
      originalItems.add(gi); 
     } 
    } 

    @Override 
    public int getCount() { 
     synchronized (mLock) { 
      return items != null ? items.size() : 0; 
     } 
    } 

    @Override 
    public FacebookUser getItem(int item) { 
     FacebookUser gi = null; 
     synchronized (mLock) { 
      gi = items != null ? items.get(item) : null; 

     } 
     return gi; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View rowView = convertView; 
     final FacebookUser fcbu = getItem(position); 

     if (convertView == null) { 
      LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
        Context.LAYOUT_INFLATER_SERVICE); 
      rowView = vi.inflate(R.layout.facebook_friendslist_row, null); 
      final ViewHolder holder = new ViewHolder(); 
      holder.text = (TextView) rowView 
        .findViewById(R.id.facebook_rowFriendName); 
      holder.image = (ImageView) rowView 
        .findViewById(R.id.facebookRowUserFoto); 
      holder.checkbox = (CheckBox) rowView 
        .findViewById(R.id.chkInviteFacebookFriend); 
      holder.checkbox 
        .setOnCheckedChangeListener(new OnCheckedChangeListener() { 
         @Override 
         public void onCheckedChanged(CompoundButton buttonView, 
           boolean isChecked) { 
          FacebookUser element = (FacebookUser) holder.checkbox 
            .getTag(); 
          element.setSelected(buttonView.isChecked()); 
          holder.checkbox.setTag(element); 
         } 
        }); 
      rowView.setTag(holder); 
      holder.checkbox.setTag(fcbu); 

     } else { 
      rowView = convertView; 
      ((ViewHolder) rowView.getTag()).checkbox.setTag(fcbu); 

     } 
     ViewHolder holder = (ViewHolder) rowView.getTag(); 

     String imageurl = "http://graph.facebook.com/" + fcbu.getId() 
       + "/picture"; 
     holder.text.setText(fcbu.getName()); 
     holder.image.setTag(imageurl); 
     holder.checkbox.setChecked(fcbu.isSelected()); 

     imageLoader.DisplayImage(imageurl, holder.image); 
     return rowView; 
    } 

    /** 
    * Implementing the Filterable interface. 
    */ 
    public Filter getFilter() { 
     if (filter == null) { 
      filter = new FBAdapterFilter(); 
     } 
     return filter; 
    } 

    /** 
    * Custom Filter implementation for the items adapter. 
    * 
    */ 
    private class FBAdapterFilter extends Filter { 
     protected FilterResults performFiltering(CharSequence prefix) { 
      // Initiate our results object 
      FilterResults results = new FilterResults(); 

      // No prefix is sent to filter by so we're going to send back the 
      // original array 
      if (prefix == null || prefix.length() == 0) { 
       synchronized (mLock) { 
        results.values = originalItems; 
        results.count = originalItems.size(); 
       } 
      } else { 
       synchronized (mLock) { 
        // Compare lower case strings 
        String prefixString = prefix.toString().toLowerCase(); 
        final ArrayList<FacebookUser> filteredItems = new ArrayList<FacebookUser>(); 
        // Local to here so we're not changing actual array 
        final ArrayList<FacebookUser> localItems = new ArrayList<FacebookUser>(); 
        localItems.addAll(originalItems); 
        final int count = localItems.size(); 

        for (int i = 0; i < count; i++) { 
         final FacebookUser item = localItems.get(i); 
         final String itemName = item.getName().toString() 
           .toLowerCase(); 

         // First match against the whole, non-splitted value 
         if (itemName.startsWith(prefixString)) { 
          filteredItems.add(item); 
         } else { 
         } /* 
         * This is option and taken from the source of 
         * ArrayAdapter final String[] words = 
         * itemName.split(" "); final int wordCount = 
         * words.length; 
         * 
         * for (int k = 0; k < wordCount; k++) { if 
         * (words[k].startsWith(prefixString)) { 
         * newItems.add(item); break; } } } 
         */ 
        } 

        // Set and return 
        results.values = filteredItems; 
        results.count = filteredItems.size(); 
       }// end synchronized 
      } 

      return results; 
     } 

     @SuppressWarnings("unchecked") 
     @Override 
     protected void publishResults(CharSequence prefix, FilterResults results) { 
      // noinspection unchecked 
      synchronized (mLock) { 
       final ArrayList<FacebookUser> localItems = (ArrayList<FacebookUser>) results.values; 
       notifyDataSetChanged(); 
       clear(); 
       // Add the items back in 
       for (Iterator iterator = localItems.iterator(); iterator 
         .hasNext();) { 
        FacebookUser gi = (FacebookUser) iterator.next(); 
        add(gi); 
       } 
      }// end synchronized 
     } 
    } 

    public ArrayList<FacebookUser> getSelectedItems() { 
     ArrayList<FacebookUser> result = new ArrayList<FacebookUser>(); 
     for (FacebookUser friend : items) { 
      if (friend.isSelected()) 
       result.add(friend); 
     } 
     return result; 
    } 
} 

我也上載的AsyncTask Facebook上的朋友,所以我改變了這種方式,使適配器在postExecute填充:

@Override 
     protected void onPostExecute(ArrayList<FacebookUser> result) { 

      if (result != null && result.size() > 0) { 
       facebookAdapter = new FBAdapter(
         InviteFriendsFromFacebookActivity.this, 
         R.layout.facebook_friendslist_row, result); 
       facebookListView.setAdapter(facebookAdapter); 
       facebookListView.setVisibility(View.VISIBLE); 
       facebookAdapter.notifyDataSetChanged(); 
      } 

     } 

現在這個問題已經一去不復返了。謝謝