Фильтр ListView ArrayAdapter - дублирующиеся элементы - PullRequest
0 голосов
/ 13 октября 2011

Я пытаюсь отфильтровать просмотр списка с помощью специального адаптера.Когда я начинаю вводить текст редактирования, представление списка должно быть отфильтровано.Ниже приведен код адаптера.Пользовательский объект имеет переопределенный метод toString, который возвращает имя пользователя facebook.Я не переопределял методы ArrayAdapter getItem, добавлял или удалял.

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);
        }
    };

Все работает нормально, ожидайте, что послесписок фильтруется, отфильтрованные элементы дублируются.

А был бы признателен за любую идею, которая может вызвать это.Спасибо

1 Ответ

5 голосов
/ 17 октября 2011

Я решил проблему благодаря Как написать собственный фильтр для ListView с 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;
    }
}

Я также загрузилдрузья из Facebook на AsyncTask, поэтому я изменил этот способ, чтобы адаптер заполнялся в 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();
            }

        }

Теперь проблема исчезла.Спасибо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...