Insert a RecyclerView inside another RecyclerView
Asked Answered
I

2

4

I am creating a set of 5 cards with the style of Google Now Cards. I am focusing first with the layout in general.

I'm using CardView and RecyclerView and what I want to achieve is something like this:

enter image description here

This is my CardAdapter(Also the general adapter):

public class CardAdapter extends RecyclerView.Adapter<CardAdapter.cardViewHolder> {
private ArrayList<Card> item;
public CardAdapter(ArrayList<Card> item){
    this.item = item;
}

@Override
public cardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_layout,parent,false);
    cardViewHolder card = new cardViewHolder(v);
    return card;
}

@Override
public void onBindViewHolder(cardViewHolder holder, int position) {
    holder.titel.setText(item.get(position).getTitel());
    holder.card_icon.setImageResource(item.get(position).getIcon());
    holder.load_more.setText("Load more");
}

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

public static class cardViewHolder extends RecyclerView.ViewHolder{
    TextView titel;
    ImageView card_icon;
    RecyclerView list_content;
    TextView load_more;
    public cardViewHolder(View itemView){
        super(itemView);
         titel = (TextView)itemView.findViewById(R.id.titel);
        card_icon = (ImageView)itemView.findViewById(R.id.card_icon);
        load_more = (TextView)itemView.findViewById(R.id.loadmore);
        list_content = (RecyclerView)itemView.findViewById(R.id.list_content);
    }

}}

This is the MensaCardAdapter(the adapter for the first card, as far as I know everycard should have a particular adapter since they all have different layouts)

public class MensaCardAdapter extends RecyclerView.Adapter<MensaCardAdapter.MensaViewHolder> {
private List<MensaRow> items;

public MensaCardAdapter(List<MensaRow> items) {
    this.items = items;
}



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

@Override
public void onBindViewHolder(MensaViewHolder holder, int position) {
    holder.content.setText(items.get(position).getMensa_row_content());
    holder.img.setImageResource(items.get(position).getMensa_row_img());
    holder.title.setText(items.get(position).getTitel());
}

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

public class MensaViewHolder extends RecyclerView.ViewHolder{
    private ImageView img;
    public TextView title;
    public TextView content;

    public MensaViewHolder(View itemView){
        super(itemView);
        img = (ImageView)itemView.findViewById(R.id.mensa_row_img);
        title = (TextView)itemView.findViewById(R.id.mensa_row_title);
        content = (TextView)itemView.findViewById(R.id.mensa_row_content);
    }
}}

This is the CardLayout (for all the cards)

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="110dp"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp"
android:padding="15dp"
android:layout_margin="5dp">


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/card_icon"
        android:layout_width="25dp"
        android:layout_height="25dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="15dp"
        android:layout_marginTop="15dp" />

    <TextView
        android:id="@+id/titel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Card Title"
        android:textSize="18dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_alignTop="@+id/card_icon"
        android:layout_alignLeft="@+id/list_content"
        android:layout_alignStart="@+id/list_content"
        android:layout_marginLeft="18dp"
        android:layout_marginStart="18dp" />

    <android.support.v7.widget.RecyclerView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/list_content"
        android:layout_width="match_parent"
        android:layout_height="30dp"
        android:scrollbars="vertical"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/card_icon"
        android:layout_toEndOf="@+id/card_icon" />

    <TextView
        android:id="@+id/loadmore"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Load More"
        android:textSize="12dp"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_marginLeft="100dp"
        android:layout_marginStart="100dp"
        android:layout_alignParentBottom="true"
        android:layout_alignLeft="@+id/titel"
        android:layout_alignStart="@+id/titel"
        android:layout_marginBottom="5dp" />

</RelativeLayout>

And this is the MensaCardLayout(layout for the first card)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ImageView
    android:layout_width="15dp"
    android:layout_height="15dp"
    android:layout_marginLeft="31dp"
    android:layout_marginStart="31dp"
    android:id="@+id/mensa_row_img"
    android:layout_marginTop="22dp"
    android:layout_alignParentTop="true"
    android:layout_alignParentLeft="true"
    android:layout_alignParentStart="true" />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="15dp"
    android:text="Angebot 1"
    android:layout_marginLeft="15dp"
    android:layout_marginStart="19dp"
    android:id="@+id/mensa_row_title"
    android:layout_alignTop="@+id/mensa_row_img"
    android:layout_toRightOf="@+id/mensa_row_img"
    android:layout_toEndOf="@+id/mensa_row_img" />
<TextView
    android:layout_width="wrap_content"
    android:layout_height="30dp"
    android:text="Content"
    android:layout_below="@+id/mensa_row_title"
    android:layout_alignLeft="@+id/mensa_row_title"
    android:layout_alignStart="@+id/mensa_row_title"
    android:layout_marginTop="18dp"
    android:id="@+id/mensa_row_content" />

1- I can create the cards with no RecyclerView inside them without problems, but I have no idea how to write the activitymain class with 1 general RecyclerView and 5 independent and different RecyclerView.

The thing is that every card has different layout and different content, I am very new to android and I really don't understand any other complicated examples

Any help will be appreciated

Insufficiency answered 4/11, 2016 at 11:20 Comment(3)
You should not insert RecyclerView into another RecyclerView, this may cause many problems, and Google didn't recommend that. you should find another way.Overreach
What any other way do you recommend me?Insufficiency
I think you can put all the data into the outer RecyclerView, the header and footer can also be managed by the outer RecyclerView with different item typeOverreach
G
0

I investigated some of the same problems of rendering list inside an item of parent list. There's the other question that helped me to solve this case.

Hope you'll be able to solve this case with it.

Gildea answered 11/8, 2017 at 11:1 Comment(0)
C
0

This implementation is horizontal grid recycler view inside a vertical Liner recycler view

Activity

class RecyclerGridActivity : AppCompatActivity() {

    private lateinit var listAdapter: RecyclerCustomListAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_recycler_grid)

        val recyclerListView = findViewById<RecyclerView>(R.id.recyclerCustomList)

        listAdapter = RecyclerCustomListAdapter()
        recyclerListView.layoutManager = LinearLayoutManager(this@RecyclerGridActivity)
        recyclerListView.adapter = listAdapter
        recyclerListView.addItemDecoration(TopSpacingItemDecoration(10))
        listAdapter.setContent(arrayOf(1,2,3,4), Example.shared.getData(), WeakReference(this))


    }
}

It's layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    tools:context=".views.recycler_grid_view.RecyclerGridActivity">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerCustomList"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

vertical Liner recycler Adapter

class RecyclerCustomListAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    private lateinit var items: Array<Int>

    private lateinit var data: List<User>

    private lateinit var gridAdapter: RecyclerGridAdapter

    private lateinit var ctx: WeakReference<Context>

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        gridAdapter = RecyclerGridAdapter()

        return ListViewHolder(
                LayoutInflater.from(parent.context).inflate(R.layout.layout_custom_list_item, parent, false)
        )
    }

    fun setContent(items: Array<Int>, data: List<User>, ctx: WeakReference<Context>) {
        this.items = items
        this.data = data
        this.ctx = ctx
    }


    override fun getItemCount(): Int {
        return items.size
    }

    class ListViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val recyclerGridView = itemView.findViewById<RecyclerView>(R.id.recyclerGrid)

        fun bind(data: List<User>, adapter: RecyclerGridAdapter, ctx: WeakReference<Context>) {

            recyclerGridView.layoutManager = GridLayoutManager( ctx.get(), 1, GridLayoutManager.HORIZONTAL, false)
            recyclerGridView.adapter = adapter
            recyclerGridView.addItemDecoration(TopSpacingItemDecoration(10))
            adapter.setContent(data)
        }

    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is ListViewHolder-> {
                holder.bind(data, gridAdapter, ctx)
            }
        }
    }
}

It's layout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp"
    android:orientation="vertical">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerGrid"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#4CAF50" />
</LinearLayout>

horizontal grid recycler Adapter

class RecyclerGridAdapter: RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    private lateinit var items: List<User>

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return GridViewHolder(
                LayoutInflater.from(parent.context).inflate(R.layout.layout_legacy_grid_item, parent, false)
        )
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        when (holder) {
            is GridViewHolder -> {
                holder.bind(items[position])
            }
        }
    }

    fun setContent(items: List<User>) {
        this.items = items
    }


    override fun getItemCount(): Int {
        return items.size
    }

    class GridViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        private val emailLabel = itemView.findViewById<TextView>(R.id.legacyGridEmail)

        fun bind(user: User) {
            emailLabel.text = user.email
        }
    }

}

It's layout

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView 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="200dp"
    app:cardCornerRadius="10dp"
    app:cardElevation="5dp">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_marginStart="32dp"
            android:layout_marginTop="32dp"
            android:layout_marginEnd="32dp"
            android:layout_marginBottom="60dp"
            android:scaleType="fitCenter"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:srcCompat="@android:drawable/presence_away" />

        <TextView
            android:id="@+id/legacyGridEmail"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:layout_marginBottom="16dp"
            android:text="Email"
            android:textSize="20sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/imageView2" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>

Data class

class Example private constructor() {

companion object {
    //single instance
    val shared: Example by lazy { Example() }
}

fun getData() : List<User> {
    return listOf(
        User("[email protected]", "malith", "url"),
        User("[email protected]", "malith", "url"),
        User("[email protected]", "malith", "url"),
        User("[email protected]", "malith", "url"),
        User("[email protected]", "malith", "url")
    )
}

}

Clatter answered 31/5, 2021 at 20:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.