Проблемы с использованием палитры с GridView

При реализации Palette с моим GridView у меня возникают проблемы с прокруткой.

По сути, вот ситуация: каждый из элементов в GridView имеет строку заголовка и загружаемое изображение. При использовании палитры строка заголовка должна измениться на извлеченный цвет, который извлекает палитра.

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

Вот пример:

введите здесь описание изображения

Затем, когда я прокрутил вниз и снова прокрутил вверх:

введите здесь описание изображения

Кроме того, расцветка кажется не совсем правильной, не так ли? по какой-то причине кажется, что он просто выбирает последний загруженный цвет, а иногда он даже не загружается вообще, как вы можете видеть, глядя на полоски.

Я делаю это в своем альбомном адаптере, вот код, и, надеюсь, кто-то может направить меня в правильном направлении.

public class AlbumAdapterNew extends ArrayAdapter<String> {

ArrayList<String> names;
Activity context;
ArrayList<String> coverPaths;
String coverPath;
Drawable img;
Bitmap bitmap;
ViewHolder mViewHolder = null;
ImageLoader imageLoader = ImageLoader.getInstance();
private RelativeLayout background;

static class ViewHolder {

    private TextView text;
    private ImageView image;

}

public AlbumAdapterNew(Activity context, ArrayList<String> names,
        ArrayList<String> coverPaths) {
    super(context, R.layout.albums_row, names);

    this.names = names;
    this.context = context;
    this.coverPaths = coverPaths;

    DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()

    .displayer(new FadeInBitmapDisplayer(500))

    .build();
    ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(
            context)

    .defaultDisplayImageOptions(defaultOptions)

    .build();
    ImageLoader.getInstance().init(config); // Do it on Application start

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub

    if (convertView == null) {
        mViewHolder = new ViewHolder();
        LayoutInflater vi = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = vi.inflate(R.layout.albums_row, parent, false);
        mViewHolder.text = (TextView) convertView
                .findViewById(R.id.albumTextView);
        mViewHolder.image = (ImageView) convertView
                .findViewById(R.id.album_photo);
        background = (RelativeLayout) convertView
                .findViewById(R.id.containerText);
        convertView.setTag(mViewHolder);

    }

    else {

        mViewHolder = (ViewHolder) convertView.getTag();

    }

    mViewHolder.text.setText(names.get(position));

    if (coverPaths.get(position) != null && !coverPaths.isEmpty()) {

        mViewHolder.image.setScaleType(ScaleType.CENTER_CROP);

        Glide.with(context).load("file:///" + coverPaths.get(position))
                .asBitmap()
                .into(new BitmapImageViewTarget(mViewHolder.image) {
                    @Override
                    protected void setResource(Bitmap resource) {
                        // Do bitmap magic here

                        Palette.from(resource).generate(
                                new Palette.PaletteAsyncListener() {
                                    public void onGenerated(Palette palette) {
                                        Palette.Swatch vibrantSwatch = palette
                                                .getVibrantSwatch();
                                        if (vibrantSwatch != null) {

                                            background
                                                    .setBackgroundColor(vibrantSwatch
                                                            .getRgb());

                                        }
                                    }
                                });

                        super.setResource(resource);
                    }
                });

    } else {

        mViewHolder.image.setScaleType(ScaleType.CENTER_INSIDE);

        imageLoader.displayImage("drawable://" + R.drawable.music_record,
                mViewHolder.image);

    }

    return convertView;
}

}

person Jack    schedule 02.07.2015    source источник
comment
Ваш код проходит через if (coverPaths.get(position) != null && !coverPaths.isEmpty()) для каждой ячейки при прокрутке вверх? Возможно, нет, и это может быть проблемой (поскольку Palette используется только там).   -  person shkschneider    schedule 02.07.2015
comment
Почему бы ему не пройти через это снова? это не имеет большого смысла для меня.   -  person Jack    schedule 02.07.2015
comment
Моя идея заключалась в том, что переработанный вид был неправильным или исходное изображение было неправильным. Но это была всего лишь идея, точного ответа у меня нет, поэтому простой комментарий :)   -  person shkschneider    schedule 02.07.2015
comment
хм, да, это единственное, может быть, единственное логическое объяснение неправильным цветам. Я не уверен, что я могу сделать.   -  person Jack    schedule 02.07.2015
comment
Я также нашел еще один вопрос, на который не ответили с той же проблемой, что и у меня - stackoverflow.com/questions/27498142/   -  person Jack    schedule 02.07.2015


Ответы (1)


Когда вы создаете свой Palette, вы должны сохранить его в свой ViewHolder в обратном вызове. Помимо того, что Palette дорого создавать, это всегда синхронизирует ваши экземпляры Palette с обрабатываемым элементом сетки, когда вы связываете данные из ViewHolder.

РЕДАКТИРОВАТЬ: В соответствии с просьбой, своего рода пример. У меня не было под рукой компьютера с SDK, так что это по памяти, но это должно направить вас в правильном направлении!

    public class AlbumAdapterNew extends ArrayAdapter<String> {

    ArrayList<String> names;
    Activity context;
    ArrayList<String> coverPaths;
    String coverPath;
    Drawable img;
    Bitmap bitmap;
    ImageLoader imageLoader = ImageLoader.getInstance();

    static class ViewHolder {

        private TextView text;
        private ImageView image;
        private Palette palette;
        private RelativeLayout background;

    }

    public AlbumAdapterNew(Activity context, ArrayList<String> names,
                           ArrayList<String> coverPaths) {
        super(context, R.layout.albums_row, names);

        this.names = names;
        this.context = context;
        this.coverPaths = coverPaths;

        DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
            .displayer(new FadeInBitmapDisplayer(500))
            .build();

        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
            .defaultDisplayImageOptions(defaultOptions)
            .build();
        ImageLoader.getInstance().init(config); // Do it on Application start

    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // This should be local so you don't get conflicts
        ViewHolder viewHolder;

        if (convertView == null) {
            viewHolder = new ViewHolder();
            LayoutInflater vi = LayoutInflater.from(parent.getContext());
            convertView = vi.inflate(R.layout.albums_row, parent, false);
            viewHolder.text = (TextView) convertView
                    .findViewById(R.id.albumTextView);
            viewHolder.image = (ImageView) convertView
                    .findViewById(R.id.album_photo);
            viewHolder.background = (RelativeLayout) convertView
                    .findViewById(R.id.containerText);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        viewHolder.text.setText(names.get(position));

        if (coverPaths.get(position) != null && !coverPaths.isEmpty()) {
            viewHolder.image.setScaleType(ScaleType.CENTER_CROP);
            Glide.with(context)
                    .load("file:///" + coverPaths.get(position))
                    .asBitmap()
                    .into(new BitmapImageViewTarget(viewHolder.image) {
                        @Override
                        protected void setResource(Bitmap resource) {
                            // Do bitmap magic here

                            if(viewHolder.palette != null) {
                                setViewBackgroundColor(viewHolder)
                            } else {
                                Palette.from(resource).generate(
                                    new Palette.PaletteAsyncListener() {
                                        public void onGenerated(Palette palette) {
                                            viewHolder.palette = palette;
                                            setViewBackgroundColor(vh);
                                        }
                                    });
                            }
                            super.setResource(resource);
                        }
                    });
        } else {
            mViewHolder.image.setScaleType(ScaleType.CENTER_INSIDE);
            imageLoader.displayImage("drawable://" + R.drawable.music_record,
                    mViewHolder.image);
        }

        return convertView;
    }

    private void setViewBackgroundColor(ViewHolder vh) {
        Palette.Swatch swatch = vh.palette.getVibrantSwatch();
        if(swatch != null) {
            vh.background.setBackgroundColor(swatch.getRgb());
        }
    }
}
person berwyn    schedule 02.07.2015
comment
Действительно хорошее замечание (Palette все еще дорого), но я думаю, что это должен быть комментарий, поскольку он не решает проблему OP. - person shkschneider; 02.07.2015
comment
Да, дорогая часть была в стороне, но кеширование палитры и ее использование из ViewHolder должно решить проблему, так как это не должно пересчитываться на лету и использовать устаревшие ссылки на представления. - person berwyn; 02.07.2015
comment
Не могли бы вы привести пример того, как я могу использовать его с моего View Holder, пожалуйста? - person Jack; 02.07.2015
comment
Кроме того, если вы это сделаете, доступ к палитре не будет осуществляться статически, как говорится. - person Jack; 02.07.2015
comment
Я отредактировал свой ответ с образцом кода, который должен помочь вам начать работу! - person berwyn; 02.07.2015
comment
@atomicrat2552 Большое спасибо за пример. Я пробовал этот код, и проблема все еще сохраняется, когда я прокручиваю вверх :(. - person Jack; 03.07.2015