-1

So, I have a recycler view and the items inside a recyclerview are dynamic. That is there can be one card or two cards. as you can see the recyclerview index 1 has only one item, whereas recyclerview index 0 has two cards. How can I achieve this? enter image description here

Ashutosh
  • 151
  • 12
  • 1
    You can do that by useing `nested recyclerview`. for example see this [nested-recyclerview-or-inner-recycler](http://mithunkumarc.blogspot.com/2016/09/nested-recyclerview-or-inner-recycler.html) – Jakir Hossain Nov 13 '19 at 05:52
  • @JakirHossain how do I implement itemclick listener on those inside cards? – Ashutosh Nov 13 '19 at 13:57

3 Answers3

4

You can do that using nested recylerview means reacyclerview insiderecyclerview.

You can follow the below way.

activity_main.xml

<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</android.support.constraint.ConstraintLayout>

MainActivity.java

public class MainActivity extends  AppCompatActivity implements YourInterface {

    RecyclerView recyclerView;

    private CategoryAdapter adapter;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setUpRecyclerView();


        // add your data to your arraylist and pass it to setInfoToAdapter method like below

        ArrayList<CategoryItem> categoryItemList = new ArrayList<>();
        categoryItemList.add(new CategoryItem("Item Title"))

        categoryList.add(new Category("Section Title", categoryItemList));

        setInfoToAdapter(categoryList );
     }

    //setup recycler view
    private void setUpRecyclerView() {
        recyclerView = findViewById(R.id.recyclerView);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
    }


    private void setInfoToAdapter(List<Category> categoryList) {
        adapter = new CategoryAdapter(this, categoryList, this); // here last parameters for your inteface
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void doSomething(String title) {
        // here you can do whatever you want it tigger when item adapter call this method.
    }
}

CategoryAdapter.java

public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.CategorySectionHolder> {
    private Context context;
    private List<Category> categoryList;
    private YourInterface interface;

    public CategoryAdapter(Context context, List<Category> categoryList,YourInterface interface) {
        this.context = context;
        this.categoryList = categoryList;
        this.interface = interface; //

    }

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

    @Override
    public void onBindViewHolder(CategorySectionHolder holder, int position) {
        final Category category = categoryList.get(position);
        final String categoryName = category.getName();
        holder.tvSectionLabel.setText(categoryName);

        // data set for your items
        final ArrayList<CategoryItem> itemList =category.getItems(); // here you got your item list for each category

        // adapter for your items
        final CategoryItemAdapter adapter;
        adapter = new CategoryItemAdapter(context, itemList, interface);

        //recycler view for items
        holder.rvCategoryItems.setHasFixedSize(true);
        holder.rvCategoryItems.setNestedScrollingEnabled(false);
        holder.rvCategoryItems.setLayoutManager(new LinearLayoutManager(context));
        holder.rvCategoryItems.setAdapter(adapter);
    }

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

    public static class CategorySectionHolder extends RecyclerView.ViewHolder {

        TextView tvSectionLabel;
        RecyclerView rvCategoryItems;

        public CategorySectionHolder(View itemView) {
            super(itemView);
            // initialize your views here
            tvSectionLabel = itemView.findViewById(R.id.tvSectionLabel);
            rvCategoryItems = itemView.findViewById(R.id.rvCategoryItem);
        }
    }
}

And category_section_row design for CategoryAdapter which have a recyclerview.

category_section_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="@dimen/_5sdp">

    <TextView
        android:id="@+id/tvSectionLabel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Label"
        android:layout_alignParentLeft="true"
        android:textStyle="bold"
        android:textColor="@android:color/darker_gray"
        android:textSize="@dimen/_14ssp" />

    <!--  recycler view for items -->
    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvCategoryItem"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/tvSectionLabel"
        android:layout_marginTop="@dimen/_5sdp" />
</RelativeLayout>

And Adapter for items

CategoryItemAdapter.java

public class CategoryItemAdapter extends RecyclerView.Adapter<CategoryItemAdapter.CategoryItemsHolder> {
    private Context context;
    private List<CategoryItem> itemModels;

    private YourInterface interface;

    public CategoryItemAdapter(Context context, List<CategoryItem> itemModels,YourInterface interface) {
        this.context = context;
        this.itemModels = itemModels;
        this.interface = interface;
    }

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

    @Override
    public void onBindViewHolder(final CategoryItemsHolder holder, final int position) {

        holder.itemName.setText(itemModels.get(position).getTitle());

        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // here you can do whatever you want to click of item cardview.

                // here you call method of your interface 
                interface.doSomething("Hello from item adapter")
            }
        });

    }

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

    public static class CategoryItemsHolder extends RecyclerView.ViewHolder {
        TextView itemName;
        CardView cardView
        public CategoryItemsHolder(View itemView) {
            super(itemView);
            // initialize your views here.
            itemName = itemView.findViewById(R.id.tvItemNameCategory);
            cardView = itemView.findViewById(R.id.cardView);
        }
    }
}

category_item_row.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/cardView"
    app:cardBackgroundColor="@color/black"
    app:cardCornerRadius="@dimen/_3sdp"
    app:cardElevation="@dimen/_3sdp">

    <android.support.constraint.ConstraintLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="vertical">

        <TextView
            android:id="@+id/tvItemNameCategory"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="?android:selectableItemBackground"
            android:fontFamily="sans-serif"
            android:padding="@dimen/_5sdp"
            android:text="@string/app_name"
            android:textColor="@color/white"
            android:textSize="@dimen/_14ssp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintTop_toTopOf="parent" />  

         <!--Your other view goes there-->

    </android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>

And finally, your Model class should be like the following.

Category.java

public class Category{
    private String name;
    private ArrayList<CategoryItems> items;

    public Category(String name, ArrayList<CategoryItems> items) {
        this.name = name;
        this.items = items;

    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name= name;
    }

    public ArrayList<CategoryItems> getItems() {
        return items;
    }

    public void setItems(ArrayList<CategoryItems> items) {
        this.items= items;
    }

   public class CategoryItems{
       private String title;

       public Category(String title) {
          this.title = title;
       }

       public String getTitle() {
           return title;
       }

       public void setTitle(String title) {
           this.title= title;
       }
   }
}

Update: create an interface like that

interface YourInterface{
   public void doSomething(String title); //here you can use parameters as you want
}

Now you have to implement this interface in YourActivit in this case in MainActivity. And pass instance of MainActivity to CategoryAdapter then CategoryItemAdapter. see these classes I have updated.

Jakir Hossain
  • 3,830
  • 1
  • 15
  • 29
  • Good answer, how to create an interface for child recycler views so that i can access them from category activities? – Ashutosh Nov 13 '19 at 15:15
  • 1
    Thanks you're a lifesaver. – Ashutosh Nov 13 '19 at 16:10
  • how about multiple type of data? let's say in category data class there could be another list of ummm cloths and console how about showing them as well, as far as i'm trying it shows either of list not both at once... – USMAN osman Mar 15 '20 at 15:04
0

In Recycler adaptre in onCreateViewHolder add if else or switch case for multiple ui layouts

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == LAYOUT_TYPE_ONE) {
            View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type_one, parent, false);
            return new FeedViewHolder(layoutView);
        } else {
            View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_type_two, parent, false);
            return new FeedViewHolder(layoutView);
        }
    }
Ganesh Pokale
  • 1,538
  • 1
  • 14
  • 28
0

you can use notifyDataSetChange(); on your adapter to update recycler every