0

I am tryin to create a RecyclerView which displays a list of cars along with various tags for each row item.

For example:

BMW

v6,turbo ---> Tags

Merc

V8, Twin-turbo, Carbon-Fiber ---> Tags

The problem being the tags are retrieved in a JSON response and can be of variable number. However, the title of the RecyclerView has only one textView at all times.

My current code has a simple RecyclerView where i am able to display the name of the various cars, however i am not sure how can i do a dynamic addition of the various tags below the fixed title based on the response.

Code:

 public class ListItemRecyclerViewAdapter extends RecyclerView.Adapter<ListItemRecyclerViewAdapter.ViewHolder>{
        private List<BaseItem> listOfItems = new ArrayList<>();
        private final List<TextView> textViewPool = new LinkedList<>();
        public ListItemRecyclerViewAdapter(List<BaseItem> listItems){

        }
        @NonNull
        @Override
        public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.fragment_list_item, parent, false);
            return new ViewHolder(view);
        }

        @Override
        public int getItemCount() {
            return listOfItems.size();
        }

        @Override
        public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
            holder.carName.setText(((NewsItem)listOfItems.get(position)).getCar());


           Categories categories = ((ListItem)listOfItems.get(position)).getCategories();
           List<String> categoriesList = categories.getCategories();
            holder.bindViewForChips(categoriesList);
        }



        @Override
        public void onViewRecycled(@NonNull NewsViewHolder holder) {
            super.onViewRecycled(holder);
            holder.recycleTextViews();
        }

        // Clean all elements of the recycler
        private void clear() {
            listOfItems.clear();
        }

        public void addAll(List<BaseItem> list) {
            clear();
            listOfItems.addAll(list);
            notifyDataSetChanged();
        }

  class ViewHolder extends RecyclerView.ViewHolder{

        @BindView(R.id.car)
        TextView carName;

        private final List<TextView> textViews = new ArrayList<>();
        private final ViewGroup container;

        ViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this,itemView);
            container = (ViewGroup) itemView;
        }

        private void bindViewForChips(List<String> categories){
            recycleTextViews();
            for (int i = 0; i < categories.size(); i++) {
                final TextView textView = getRecycledTextViewOrCreate();
                textViewPool.add(textView);
                container.addView(textView);
            }
        }

        private TextView getRecycledTextViewOrCreate() {
          //  if (textViewPool.isEmpty()) {
                return (TextView)LayoutInflater.from(container.getContext()).inflate(R.layout.chips_view, container, false);
            //}
            //return textViewPool.remove(0);
        }

        public void recycleTextViews() {
            textViewPool.addAll(textViews);
            textViews.clear();
            container.removeAllViews();
        }
    }
    }

Any help is appreciated. Thanks!

user2511882
  • 9,022
  • 10
  • 51
  • 59

1 Answers1

1

IMO it depends somewhat on your UI as well. If you just want to show tags in comma separated format, you can loop through the tags array and create a string using StringBuilder and assign it to a TextView.

You can also use recyclerView inside recyclerView, but I think that could be an overkill for this situation. You can go for this option if tags are going to be clickable. This way you can style each tag element as well. Or maybe a staggered list could also look good.

Option 1: Show all tags in a single TextView. In that case your list item xml will be like this.

<TextView>BMW</TextView>
<TextView>ConcatenatedTagsFromArray</TextView>

Option 2: Show tags in a child RV. In that case parent list item xml will be like this.

<TextView>BMW</TextView>
<recyclerView>childRecyclerViewID</recyclerView>

And then create a recyclerview object inside onBindViewHolder method of parent RV and set layout manager and adapter and pass tags array as data. You will also need a new list item xml for child recycler view's items(However you want your tag to look like).

Ranjan
  • 1,096
  • 10
  • 22
  • But my tag number will be variable. If i use a recyclerview i would need to know the number of views before hand to design my layout xml accordingly. – user2511882 Jun 19 '18 at 18:18
  • You will pass the tags array to the child recyclerview which will get item count from that array's size and layout xml will be for each item(tag in this case). – Ranjan Jun 19 '18 at 18:23
  • I understand your point. However, the name and the tags have to be in the same row xml file. Not sure if my point is getting across. If you can share some sample code that would be great. – user2511882 Jun 19 '18 at 18:27
  • Can you share UI design snippet? It would be clear what you are trying to achieve. – Ranjan Jun 19 '18 at 18:29
  • Cant share snippet unfortunately. However something similar to the UI here: https://stackoverflow.com/questions/43101231/showing-a-dynamic-number-of-views-in-recyclerview-item The only difference, i also need a title along with the dynamic number of views. – user2511882 Jun 19 '18 at 18:31
  • Which one are you using? Simple `TextView` or `RecyclerView`? – Ranjan Jun 22 '18 at 10:56