Правильный вывод изображения в RecyclerView в адаптере

222
14 октября 2017, 17:38

Реализовал в адаптере вывод картинок из assets в список RecyclerView. Элементы списка содержат картинку и два текста. Для картинки использую RoundedImageView.

Все работает и выводит, но возникает вопрос, можно ли получше сделать?

public class PlantsAdapter extends RecyclerView.Adapter<PlantsAdapter.PlantsViewHolder> implements Filterable {
    Context context;
    private ArrayList<Plant> plantsList;
    private ArrayList<Plant> mFilteredList;
    private ItemSendId itemSendId;
    public class PlantsViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public RoundedImageView iconView;
        public TextView txtName;
        public TextView txtFamily;
        public PlantsViewHolder(View view) {
            super(view);
            itemView.setOnClickListener(this);
            iconView = (RoundedImageView) view.findViewById(R.id.iconView);
            txtName = (TextView) view.findViewById(R.id.txtName);
            txtFamily = (TextView) view.findViewById(R.id.txtFamily);
        }
        @Override
        public void onClick(View view) {
            if (itemSendId != null){
                itemSendId.sendItemId(mFilteredList.get(getAdapterPosition()).getId());
            }
        }
    }
    public void setItemSendId(ItemSendId itemSendId) {
        this.itemSendId = itemSendId;
    }
    public PlantsAdapter(Context context, ArrayList<Plant> plantsList) {
        this.context = context;
        this.plantsList = plantsList;
        this.mFilteredList = plantsList;
    }
    @Override
    public PlantsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        return new PlantsViewHolder(itemView);
    }
    @Override
    public void onBindViewHolder(PlantsViewHolder holder, final int position) {
        final Plant plant = mFilteredList.get(position);
        holder.txtName.setText(plant.getRusName());
        holder.txtFamily.setText(plant.getClassification());
        System.out.println(plant.getIcon());
        InputStream inputStream = null;
        try{
            inputStream = context.getAssets().open("images/icons/" + plant.getIcon() + ".jpg");
            Drawable d = Drawable.createFromStream(inputStream, null);
            holder.iconView.setBackground(d);
        }
        catch (IOException e){
            e.printStackTrace();
        }
        finally {
            try{
                if(inputStream!=null)
                    inputStream.close();
            }
            catch (IOException ex){
                ex.printStackTrace();
            }
        }
    }
    @Override
    public int getItemCount() {
        return mFilteredList.size();
    }
    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    mFilteredList = plantsList;
                } else {
                    ArrayList<Plant> filteredList = new ArrayList<>();
                    for (Plant plant : plantsList) {
                        if (plant.getRusName().toLowerCase().contains(charString)) {
                            filteredList.add(plant);
                        }
                    }
                    mFilteredList = filteredList;
                }
                FilterResults filterResults = new FilterResults();
                filterResults.values = mFilteredList;
                return filterResults;
            }
            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                mFilteredList = (ArrayList<Plant>) filterResults.values;
                notifyDataSetChanged();
            }
        };
    }
}

Интересует собственно этот фрагмент кода, можно ли получше реализовать? Не будет ли приложение падать в каких-то случаях?

@Override
public void onBindViewHolder(PlantsViewHolder holder, final int position) {
    final Plant plant = mFilteredList.get(position);
    holder.txtName.setText(plant.getRusName());
    holder.txtFamily.setText(plant.getClassification());
    System.out.println(plant.getIcon());
    InputStream inputStream = null;
    try{
        inputStream = context.getAssets().open("images/icons/" + plant.getIcon() + ".jpg");
        Drawable d = Drawable.createFromStream(inputStream, null);
        holder.iconView.setBackground(d);
    }
    catch (IOException e){
        e.printStackTrace();
    }
    finally {
        try{
            if(inputStream!=null)
                inputStream.close();
        }
        catch (IOException ex){
            ex.printStackTrace();
        }
    }
}
Answer 1

Для отображения картинок можете использовать библиотеку Glide. Она умеет показывать картинки из ассетов. Сократится код и добавится кеширование, что улучшит производительность при прокрутке списка. Не нужно будет каждый раз читать из ассетов.

Пример:

Glide.with(context)
        .load(Uri.parse("file:///android_asset/images/icons/" + plant.getIcon() + ".jpg"))
        .into(imageView);
Answer 2

В текущей реализации мне не нравится, что Вы каждый раз открываете новый поток – это лишние ресурсы.

Я бы посоветовал не писать своего велосипеда, а воспользоваться каким-либо сторонним средством, которое уже протестировано и оптимизировано, например – Picasso:

Picasso.with(context).load("file:///android_asset/images/icons/" + plant.getIcon() + ".jpg").into(iconView);

(при использовании Picasso получаете возможность кэширования из коробки)

READ ALSO
Свой Header Renderer для JTable

Свой Header Renderer для JTable

Добрый день! Необходимо настроить заголовки таблицы JTableДля этого нашел пример как сделать свой рендерер, настроить его как надо и применить...

172
Java decoder не может распознать символ

Java decoder не может распознать символ

Возникла проблема с декодировкойПри попытке декодировать вот это "ə","ğ","ı" выдает ? но символом ü работает

185
Для чего нужен @XStreamAlias в Java?

Для чего нужен @XStreamAlias в Java?

Для чего в принципе нужен @XStreamAlias?

312