Implemented in the adapter the output of pictures from assets to the RecyclerView list. List items contain a picture and two texts. For a picture I use RoundedImageView .

Everything works and outputs, but the question arises whether it can be done better?

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

This fragment of the code actually interests, whether it is possible to implement better? Will the application not fall in some cases?

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

    2 answers 2

    To display images, you can use the Glide library. She is able to show pictures from assets. The code is reduced and caching is added, which will improve performance when scrolling through the list. It will not be necessary to read each time from assets.

    Example:

     Glide.with(context) .load(Uri.parse("file:///android_asset/images/icons/" + plant.getIcon() + ".jpg")) .into(imageView); 
    • Very handy library. I will use it) - Kolhoznik
    • Can I use it to display a single picture in an Activity? - Kolhoznik
    • Of course it is possible. Similar. - eugeneek
    • Thank you very much. - Kolhoznik

    In the current implementation, I don’t like that every time you open a new stream - these are extra resources.

    I would advise not to write my bike, but to use some third-party tool that has already been tested and optimized, for example, Picasso :

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

    (using Picasso get the possibility of caching out of the box)

    • How to choose Glide or Picasso? Which one is better? - Kolhoznik
    • @Kolhoznik; For this task, any. Glide is more functional, but also heavier. - post_zeew
    • Understood, thank you .. I will read about both and choose - Kolhoznik
    • @Kolhoznik, Look at this . - post_zeew
    • one
      @Kolhoznik Glide is also more productive (faster) Picasso and uses less resources. - pavlofff