Фильтр поиска в списке возвращает неверные результаты при нажатии элемента

Я провел достаточное количество исследований и нашел три случая, связанных с моей проблемой.

Решение 1

Решение 2

Решение 3

Я не говорю, что мой случай уникален или что-то в этом роде, просто я не могу заставить их ответы работать на меня с моим шнуром.

ПРОБЛЕМА: у меня есть listview, фильтруемый edit text сверху. Однако, когда я нажимаю на искомый элемент, я получаю результат выбора другого изображения. Текст работает нормально, но проблемы с изображениями.

Например: в списке есть строки с изображениями A, B, C, D.

При поиске C вы получаете результат, отфильтрованный как C. Но нажатие на него приводит к отображению изображения из A. Это похоже на то, что позиция не меняется для изображений, но используется исходная позиция адаптера ArrayList.

Любая помощь будет оценена.

Мой адаптер:

public class SearchListAdapter extends BaseAdapter implements Filterable {
    List<Model> mStringFilterList;
    ValueFilter valueFilter;
    ImageLoader imageLoader = AppController.getInstance().getImageLoader();
    private Activity activity;
    private LayoutInflater inflater;
    private List<Model> modelItems;
    private int mDefaultImageId;

    public SearchListAdapter(Activity activity, List<Model> modelItems) {
        this.activity = activity;
        this.modelItems = modelItems;
        mStringFilterList = modelItems;
    }


    public void setDefaultImageResId(int defaultImage) {
        mDefaultImageId = defaultImage;
    }

    @Override
    public int getCount() {
        return modelItems.size();
    }

    @Override
    public Object getItem(int location) {
        return modelItems.get(location);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        if (inflater == null)
            inflater = (LayoutInflater) activity
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        if (convertView == null)
            convertView = inflater.inflate(R.layout.search_list_row, null);

        if (imageLoader == null)
            imageLoader = AppController.getInstance().getImageLoader();
        NetworkImageView thumbNail = (NetworkImageView) convertView
                .findViewById(R.id.thumbnail);
        TextView title = (TextView) convertView.findViewById(R.id.title);
        TextView rating = (TextView) convertView.findViewById(R.id.rating);
        TextView genre = (TextView) convertView.findViewById(R.id.genre);

        Model m = modelItems.get(position);

        // thumbnail image
        thumbNail.setImageUrl(m.getThumbnailUrl(), imageLoader);
        thumbNail.setTag(position);
        // title
        title.setText(m.getTitle());

        // amount
        rating.setText(String.valueOf(m.getRating()));

        // description
        String genreStr = "";
        for (String str : m.getGenre()) {
            genreStr += str + ", ";
        }
        genreStr = genreStr.length() > 0 ? genreStr.substring(0,
                genreStr.length() - 2) : genreStr;
        genre.setText(genreStr);

        return convertView;
    }

    @Override
    public Filter getFilter() {
        if (valueFilter == null) {
            valueFilter = new ValueFilter();
        }
        return valueFilter;
    }

    private class ValueFilter extends Filter {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults();
            if (constraint != null && constraint.length() > 0) {
                ArrayList<Model> filterList = new ArrayList<Model>();
                for (int i = 0; i < mStringFilterList.size(); i++)
                    if ((mStringFilterList.get(i).getTitle().toUpperCase())
                            .contains(constraint.toString().toUpperCase())) {


                        Model m = new Model(mStringFilterList.get(i)
                                .getTitle(), mStringFilterList.get(i)
                                .getThumbnailUrl(), mStringFilterList.get(i)
                                .getRating(), mStringFilterList.get(i)
                                .getGenre());

                        filterList.add(m);
                    }
                results.count = filterList.size();
                results.values = filterList;
            } else {
                results.count = mStringFilterList.size();
                results.values = mStringFilterList;
            }
            return results;

        }

        @Override
        protected void publishResults(CharSequence constraint,
                                      FilterResults results) {
            modelItems = (List<Model>) results.values;
            notifyDataSetChanged();
        }

    }

}

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String name = ((TextView) view.findViewById(R.id.title))
                        .getText().toString();
                bitmap = ((Model) modelList.get(position)).getThumbnailUrl();
                String rate = ((TextView) view.findViewById(R.id.rating))
                        .getText().toString();
                String genres = ((TextView) view.findViewById(R.id.genre))
                        .getText().toString();

                Intent intent = new Intent(SearchActivity.this, Details.class);
                intent.putExtra(Title, name);
                intent.putExtra("images", bitmap);
                intent.putExtra(Rate, rate);
                intent.putExtra(Genre, genres);

                startActivity(intent);
            }
        });
    }

Слушатель OnItemclick:


person Steve Kamau    schedule 29.09.2015    source источник
comment
У вас есть private List<Model> modelItems в вашем адаптере, но вы используете modelList.get(position) в слушателе, почему это так? Что такое modelList? Это внутренний список адаптеров, который обновляется, и именно оттуда вы должны взять свой предмет.   -  person wasyl    schedule 05.10.2015


Ответы (4)


Вы можете изменить код

String name = ((TextView) view.findViewById(R.id.title)).getText().toString();
bitmap = ((Model) modelList.get(position)).getThumbnailUrl();
String rate = ((TextView) view.findViewById(R.id.rating)).getText().toString();
String genres = ((TextView) view.findViewById(R.id.genre)).getText().toString();

to

Model model=(Model)adapter.getItem(position);

Он получит модель, в которой вы щелкнули, и передаст эту модель как сериализованную или то, что вы хотите сделать.

Надеюсь, это решит проблему.

person Ramesh Kumar    schedule 02.10.2015
comment
и не забудьте добавить-> @Override public Object getItem(int location) { return modelItems.get(location); } в адаптере - person Rasel; 22.12.2016

использовать

 Model model = (Model) parent.getItemAtPosition(position);

для извлечения элемента из набора данных и использования этой ссылки для заполнения объекта Intent. После того, как вы отфильтруете элементы в своем адаптере, вы переопределите modelItems = (List<Model>) results.values; текущую ссылку на modelItems.

Редактировать

lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

             Model model = (Model) parent.getItemAtPosition(position);
            Intent intent = new Intent(SearchActivity.this, Details.class);
            intent.putExtra(Title, model.getTitle());
            intent.putExtra("images", model.getThumbnailUrl());
            intent.putExtra(Rate, String.valueOf(model.getRating()));
            intent.putExtra(Genre, model.getGenre());

            startActivity(intent);
        }
    });
}
person Blackbelt    schedule 29.09.2015
comment
Хорошо, я пытаюсь выяснить, куда идет первый код, который вы мне дали... извините, новичок. - person Steve Kamau; 29.09.2015
comment
Если я удалю другие строки, как я буду отображать элементы в другом действии? - person Steve Kamau; 29.09.2015
comment
Onitemclick находится в моей деятельности - person Steve Kamau; 29.09.2015
comment
Не могли бы вы обновить вопрос и показать, как вы внесли изменения, которые я вам предложил? - person Blackbelt; 04.10.2015

Похоже, вы фильтруете свой адаптер, но затем получаете элемент из исходного нефильтрованного списка. Вы должны получить элемент непосредственно с вашего адаптера. Добавьте следующий метод в ваш BaseAdapter:

public Model getItemAtPosition(int position)
{
    return model.get(position);
}

и вызовите это из своей реализации OnItemClickListener:

bitmap = adapter.getItemAtPosition(position).getThumbnailUrl();

person Marcus Hooper    schedule 06.10.2015
comment
Это мое предпочтительное решение, очень чистое и эффективное. - person Mtl Dev; 16.03.2016

Проблема в том, что onClickListener возвращает position=0, когда onClick, потому что в вашем отфильтрованном ListView есть только один элемент C index=0, где нулевой индекс относится к image A, поэтому отображается A image См. это для вашего решения: Получить исходный индекс из отфильтрованного списка просмотреть

person Rajan Kali    schedule 29.09.2015
comment
Я проверил этот пример. Очень просто понять. Но мне не удалось увидеть, где он достигает того, чего я не могу сделать. Однако я благодарен за ваше предложение +1. - person Steve Kamau; 29.09.2015
comment
Ссылка сейчас не работает - person SREE; 26.03.2018