So, i have a list of images and another list of names of those images. I want to display all the images one below other in cardviews of first column and all the names one below other on cardviews in second column. But I am getting the like this 
So, I want all the images strictly in first column and the names on second column.Below is my xml layout files fragment_practise.xml
<RelativeLayout 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="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/flash_tablebar"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
android:layout_alignParentTop="true">
<ImageView
android:id="@+id/back_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:src="@drawable/ic_arrow_back" />
</androidx.appcompat.widget.Toolbar>
<!-- RecyclerView to display the image cards -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewPractise"
android:layout_below="@id/toolbar"
android:layout_width="match_parent"
tools:listitem="@layout/item_practise_cards"
android:layout_marginTop="10dp"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp" />
</RelativeLayout>
item_practise_cards.xml
<GridLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:columnCount="2"
android:orientation="horizontal"
android:padding="8dp">
<androidx.cardview.widget.CardView
android:id="@+id/cardImagePractise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="4dp"
android:onClick="onCardClick"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
<ImageView
android:id="@+id/imageViewPractise"
android:layout_width="150dp"
android:layout_height="150dp"
android:scaleType="centerCrop" />
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="@+id/cardTextPractise"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="4dp"
android:onClick="onCardClick"
android:clickable="true"
android:foreground="?android:attr/selectableItemBackground">
<TextView
android:id="@+id/textViewPractise"
android:layout_width="wrap_content"
android:gravity="center"
android:layout_height="wrap_content"
android:text="Random Name"
android:textSize="18sp" />
</androidx.cardview.widget.CardView>
</GridLayout>
Following the Fragment class PractiseFragment.kt
package com.example.visuallithuanian.ui.activities.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.visuallithuanian.R
import com.example.visuallithuanian.adapter.PractiseAdapter
import com.example.visuallithuanian.databinding.FragmentPractiseBinding
import dagger.hilt.android.AndroidEntryPoint
class PractiseFragment : Fragment() {
lateinit var binding: FragmentPractiseBinding
lateinit var recyclerView: RecyclerView
private val imageNamesMap= HashMap<Int,String>()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
binding = FragmentPractiseBinding.inflate(layoutInflater,container,false)
(requireActivity() as AppCompatActivity).setSupportActionBar(binding.toolbar)
(requireActivity() as AppCompatActivity).supportActionBar?.setDisplayHomeAsUpEnabled(true)
populateImages()
binding.recyclerViewPractise.layoutManager = GridLayoutManager(requireContext(),2)
binding.recyclerViewPractise.adapter = PractiseAdapter(imageNamesMap)
return binding.root
}
private fun populateImages() {
// Add image resources to a list
val imageResources = listOf(
R.drawable.africa,
R.drawable.asia,
R.drawable.europe,
R.drawable.antartica,
R.drawable.australia
// Add more image resources as needed
)
// Add image names to a list in random order
val imageNames = listOf(
"Africa",
"Asia",
"Europe",
"Antarctica",
"Australia"
// Add more image names corresponding to the resources
).shuffled()
// Use the shuffled names to assign each image resource ID a corresponding name in the imageNamesMap
for (i in imageResources.indices) {
imageNamesMap[imageResources[i]] = imageNames[i]
}
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when(item.itemId){
android.R.id.home->{
requireActivity().onBackPressed()
return true
}
}
return super.onOptionsItemSelected(item)
}
// Handle card clicks for both card views
fun onCardClick(view: View,position: Int) {
// Check the clicked view's ID to identify which cardView was clicked
when (view.id) {
R.id.cardImagePractise -> {
Toast.makeText(requireContext(),"Hello Card Image",Toast.LENGTH_SHORT).show()
}
R.id.cardTextPractise -> {
Toast.makeText(requireContext(),"Hello Card Text",Toast.LENGTH_SHORT).show()
}
}
}
}
Below is the adapter class PractiseAdapter.kt
package com.example.visuallithuanian.adapter
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.cardview.widget.CardView
import androidx.recyclerview.widget.RecyclerView
import com.example.visuallithuanian.R
class PractiseAdapter(private val imageNamesMap: HashMap<Int, String>) :
RecyclerView.Adapter<PractiseAdapter.PractiseViewHolder>() {
private val imagesList: MutableList<Int> = imageNamesMap.keys.toMutableList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PractiseViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_practise_cards, parent, false)
return PractiseViewHolder(view)
}
override fun getItemCount(): Int = imagesList.size
override fun onBindViewHolder(holder: PractiseViewHolder, position: Int) {
val imageResource = imagesList[position]
val imageName = imageNamesMap[imageResource]
holder.imageViewPractise.setImageResource(imageResource)
holder.textViewPractise.text = imageName
holder.cardImagePractise.setOnClickListener {
onCardClick(it, position)
}
holder.cardTextPractise.setOnClickListener {
onCardClick(it, position)
}
}
class PractiseViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val cardImagePractise: CardView = itemView.findViewById(R.id.cardImagePractise)
val cardTextPractise: CardView = itemView.findViewById(R.id.cardTextPractise)
val imageViewPractise: ImageView = itemView.findViewById(R.id.imageViewPractise)
val textViewPractise: TextView = itemView.findViewById(R.id.textViewPractise)
}
private fun onCardClick(view: View, position: Int) {
// Check the clicked view's ID to identify which cardView was clicked
when (view.id) {
R.id.cardImagePractise -> {
// Handle image card click
Toast.makeText(view.context, "Image clicked at position $position", Toast.LENGTH_SHORT).show()
}
R.id.cardTextPractise -> {
// Handle text card click
Toast.makeText(view.context, "Text clicked at position $position", Toast.LENGTH_SHORT).show()
}
}
}
}
I believe there is some issues in xml layout file
In your case, you are setting GridLayoutManager with span count 2. Which is way its showing image items in two columns per row.
simplest solution is, set LinearLayoutManager in recyclerview with orientation vertical.
You can set LayoutManager in xml as
Or programmatically as
Hope this helps