'How to add single item between two grid row in android

Hello guys I want to display one single item between two grid row items.

I want this type of out.

enter image description here

I'm try this way but it didn't work.

My Activity layout XML activity_grid_with_single_rv.xml

<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=".Activitry.GridWithSingleRVActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvGridWithSingle"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"/>
</LinearLayout>

My Activity class GridWithSingleRVActivity.java

public class GridWithSingleRVActivity extends AppCompatActivity {
    private RecyclerView rvGridWithSingle;
    private GridWIthSingleRVAdapter gridWIthSingleRVAdapter;
    private ArrayList<GridWithSingle> gridWithSingles=new ArrayList<>();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_grid_with_single_rv);
        rvGridWithSingle=findViewById(R.id.rvGridWithSingle);
        getGridWithSingles();
        rvGridWithSingle.setLayoutManager(new GridLayoutManager(this,2));
        gridWIthSingleRVAdapter=new GridWIthSingleRVAdapter(this,gridWithSingles);
        rvGridWithSingle.setAdapter(gridWIthSingleRVAdapter);
    }

    private ArrayList<GridWithSingle> getGridWithSingles(){
        gridWithSingles.clear();
        gridWithSingles=new ArrayList<>();
        int addSingleCnt=0;
        for (int i=0;i<20;i++){
            gridWithSingles.add(new GridWithSingle(i+1,"GRID : "+(i+1)));
            if (addSingleCnt==1){
                addSingleCnt=0;
                gridWithSingles.add(new GridWithSingle(-1,"Single : "));
            }else {
                addSingleCnt++;
            }
        }
        return gridWithSingles;
    }
}

My Adapter class GridWIthSingleRVAdapter.java

public class GridWIthSingleRVAdapter extends RecyclerView.Adapter<GridWIthSingleRVAdapter.GridWIthSingleRVVH> {

    private Context context;
    private ArrayList<GridWithSingle> gridWithSingles=new ArrayList<>();
    private final int GRID_LAYOUT=1;
    private final int SINGLE_LAYOUT=0;

    public GridWIthSingleRVAdapter(Context context, ArrayList<GridWithSingle> gridWithSingles) {
        this.context = context;
        this.gridWithSingles = gridWithSingles;
    }

    @NonNull
    @Override
    public GridWIthSingleRVVH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType==GRID_LAYOUT)
        return new GridWIthSingleRVVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_grid_item,parent,false));
        else
        return new GridWIthSingleRVVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.row_single_item,parent,false));

    }

    @Override
    public void onBindViewHolder(@NonNull GridWIthSingleRVVH holder, int position) {
        if (holder.getItemViewType()==GRID_LAYOUT){
            holder.txtGrid.setText(gridWithSingles.get(position).getName());
        }else {
            holder.txtSingle.setText(gridWithSingles.get(position).getName());
        }
    }

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

    @Override
    public int getItemViewType(int position) {
        if (gridWithSingles.get(position).getId()==-1){
            return SINGLE_LAYOUT;
        }else {
            return GRID_LAYOUT;
        }
    }

    public class GridWIthSingleRVVH extends RecyclerView.ViewHolder{
        private TextView txtGrid,txtSingle;
        public GridWIthSingleRVVH(@NonNull View itemView) {
            super(itemView);
            txtGrid=itemView.findViewById(R.id.txtGrid);
            txtSingle=itemView.findViewById(R.id.txtSingle);
        }
    }
}

Two layout item xml

grid_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:id="@+id/cvGrid"
        android:layout_margin="10dp"
        app:cardCornerRadius="5dp"
        app:cardElevation="5dp"
        app:cardBackgroundColor="#EF9A9A">
        <TextView
            android:id="@+id/txtGrid"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="GRID"
            android:layout_gravity="center"
            android:textStyle="bold"
            android:textSize="18sp"
            android:textColor="@color/black"/>
    </androidx.cardview.widget.CardView>
</LinearLayout>

single_item.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:id="@+id/cvSingle"
        android:layout_margin="10dp"
        app:cardCornerRadius="5dp"
        app:cardElevation="5dp"
        app:cardBackgroundColor="#CE93D8">
        <TextView
            android:id="@+id/txtSingle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="SINGLE"
            android:layout_gravity="center"
            android:textStyle="bold"
            android:textSize="18sp"
            android:textColor="@color/black"/>
    </androidx.cardview.widget.CardView>
</LinearLayout>

Output enter image description here



Solution 1:[1]

You need to specify a spanSizeLookup for the affected columns to the layoutManager.

A couple of years ago I wrote a similar proof of concepts where the idea was to insert "ads" every 4 rows.

The project is located on GitHub.

The sample does this the trick directly in the activity by using recyclerView types and modifying the span size.

layoutManager = GridLayoutManager(this, 2)
mainRecyclerView.layoutManager = layoutManager
mainRecyclerView.adapter = adapter

layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                return when (adapter.getItemViewType(position)) {
                    adapter.viewTypeGreen -> 1
                    adapter.viewTypePurple -> 1
                    adapter.viewTypeAd -> 2
                    else -> -1
                }
            }
        }

The repository that provides this data simulates inserting a different type every 4 items

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Martin Marconcini