GridView не работает должным образом при прокрутке

У меня есть простой GridView с изображениями. Каждый элемент в GridView имеет ImageView, который показывает изображение, и другой ImageView, который становится видимым, когда изображение становится избранным (белая звезда).

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

Но я заметил, что у меня эта проблема в основном только со вторым и третьим элементом.

Это изначально выбранный и избранный элемент: Это изначально выбранный и избранный элемент

И этот элемент случайным образом выбирается и добавляется в избранное внизу при прокрутке вниз

И этот элемент случайным образом выбирается и добавляется в избранное внизу при прокрутке вниз:

Мой адаптер:

    public class ImageAdapter extends BaseAdapter {

    @Override
    public int getCount() {
        return imageUrls.length;
    }


    @Override
    public long getItemId(int position) {

        return 0;

    }

    public class ViewHolder {
        ImageView imageView;
        ProgressBar progressBar;
        ImageView imgFavorite;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder holder;


        if (convertView == null) {


            convertView = getLayoutInflater().inflate(R.layout.item_grid_image,
                    parent, false);
            holder = new ViewHolder();
            holder.imageView = (ImageView) convertView.findViewById(R.id.image);
            holder.progressBar = (ProgressBar) convertView
                    .findViewById(R.id.Itemprogress);
            holder.imgFavorite = (ImageView) convertView
                    .findViewById(R.id.selectorText);
            convertView.setTag(holder);

            inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);


            RelativeLayout relative = (RelativeLayout) convertView.findViewById(R.id.profileImageContainer);
            relative.getLayoutParams().height = width;

        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        imageLoader.displayImage(imageUrls[position], holder.imageView,
                options, new SimpleImageLoadingListener() {
                    @Override
                    public void onLoadingStarted(String imageUri, View view) {
                        holder.progressBar.setProgress(0);
                        holder.progressBar.setVisibility(View.VISIBLE);
                    }

                    @Override
                    public void onLoadingComplete(String imageUri,
                            View view, Bitmap loadedImage) {
                        holder.progressBar.setVisibility(View.GONE);

                    }
                }, null);


        if (profilePicList[position].isprofilepic && firstTime
                ) {
            currentPosition = position;
             DefaultImg = convertView;
             holder.imgFavorite.setVisibility(View.VISIBLE);
             firstTime = false;
        }


        return convertView;

    }

    @Override
    public Object getItem(int position) {
        return null;
    }

}

EDIT: добавлено в код прослушивателя кликов, где я меняю фон выбранного изображения

AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {

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

        if(mActionMode == null) {
            mActionMode = startActionMode(mActionModeCallback);
        }




        if (previousView != null) {

            ((ViewGroup) previousView).getChildAt(0).setAlpha(1.0f);
            ((ViewGroup) previousView).setBackgroundResource(0);

        }

        ((ViewGroup) view).setBackgroundResource(R.drawable.back);
        ((ViewGroup) view).getChildAt(0).setAlpha(0.3f);

        previousView = view;


    }

};

person Ado    schedule 17.07.2014    source источник


Ответы (2)


Поместите еще часть, которая может решить вашу проблему. Gridview повторно использует каждое изображение при прокрутке.

if (profilePicList[position].isprofilepic && firstTime
                ) {
            currentPosition = position;
             DefaultImg = convertView;
             holder.imgFavorite.setVisibility(View.VISIBLE); // or INVISIBLE
             firstTime = false;
 }else{
   holder.imgFavorite.setVisibility(View.GONE);
 }
person Sreejith B Naick    schedule 17.07.2014
comment
Спасибо за предложение, но теперь звезда не появляется внизу и вверху, когда я возвращаюсь наверх. - person Ado; 17.07.2014
comment
это потому, что вы используете переменную firstTime. Какая логика стоит за этим, если условие if(profilePicList[position].isprofilepic && firstTime)? - person Sreejith B Naick; 17.07.2014
comment
Да, вы правы, проблема исправлена. Теперь звезда всегда на своем месте, теперь проблема только в селекторе. Я выбираю изображения с помощью AdapterView.OnItemClickListener и меняю фон следующим образом: ((ViewGroup) view).setBackgroundResource(R.drawable.back); Любые советы по исправлению этого? - person Ado; 17.07.2014
comment
в остальном делай, ((ViewGroup)view).setBackgroundResource(R.drawable.front); - person Sreejith B Naick; 17.07.2014
comment
Я не думаю, что вы меня полностью понимаете. я меняю фон выбранного изображения в onclicklistener. Чтобы добавить в избранное изображение, которое вы не просто выбрали, вы должны нажать кнопку. Пожалуйста, посмотрите мой отредактированный ответ, который я также разместил в коде прослушивателя кликов. - person Ado; 17.07.2014
comment
imageLoader.displayImage() устанавливает изображение как исходное изображение, а не как фоновое изображение. В onclick вы устанавливаете его как фоновое изображение ((ViewGroup) view).setBackgroundResource(R.drawable.back);. Используйте imageView.setImageDrawable(context.getResources().getDrawable(R.drawable.back)); - person Sreejith B Naick; 17.07.2014
comment
Для фона я не меняю фон imageView, а фон RelativeLayout. Поэтому, когда вы нажимаете на какой-либо относительный макет изображения, фон этого изображения изменится на светло-зеленый. Является ли изменение фона в onClickListener неправильным или я должен попытаться изменить его в getView()? - person Ado; 17.07.2014
comment
Да, вы также должны написать это внутри getview().ie, if(favorited){change background and rest} else{ revert background and remove fav } - person Sreejith B Naick; 17.07.2014

Адаптеры созданы для повторного использования представлений, когда представление прокручивается так, что оно больше не видно, его можно использовать для одного из появляющихся новых представлений. Это повторно используемое представление является convertView.

Добавьте этот блок после вашего условия if (когда вы передаете imgFavorite в VISIBLE)

else 
{
   holder.imgFavorite.setVisibility(View.GONE);
   firstTime = true;
}
person Farouk Touzi    schedule 17.07.2014
comment
Спасибо за помощь, но это не работает так, как должно. Теперь звезда не появляется внизу и вверху, когда я возвращаюсь наверх. - person Ado; 17.07.2014
comment
Ваше условие в выражении if должно быть инициализировано. Попробуйте мой отредактированный ответ. - person Farouk Touzi; 17.07.2014
comment
Да, я исправил проблему с любимым изображением, но теперь выбор по-прежнему выбирается случайным образом. Пожалуйста, посмотрите мой отредактированный ответ, я добавил код слушателя. - person Ado; 17.07.2014