Tinder Swipe View with Example in Android
Last Updated :
18 Apr, 2025
Tinder Swipe View is one of the most used UI components in many Android apps. This feature provides us to easily represent the data in a huge list form. In this article, we will take a look at implementing this Swipe View feature in our Android App.
What we are going to build in this Article?
We will be building a simple application in which we will be displaying a stack of cards in which we will be displaying the different courses which are available on Geeks for Geeks. On that cards, we will be adding a swipe-like feature similar to that of Tinder. A sample GIF is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using Java/Kotlin language.

swipe left/right
Step by Step Implementation
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.
Step 2: Add below dependency in build.gradle.kts (Module :app)
Navigate to the app > Gradle Scripts > build.gradle.kts (Module :app) and add the below dependency in the dependencies section.
dependencies {
...
implementation ("com.github.yuyakaido:CardStackView:v2.3.4")
implementation ("com.github.bumptech.glide:glide:4.13.2")
}
Navigate to the app > Gradle Scripts > settings.gradle.kts and add the below line of code in the repositories section.
dependencyResolutionManagement {
...
repositories {
...
maven { setUrl("https://jitpack.io") }
}
}
After adding the above dependency now sync your project and we will move towards our activity_main.xml.
Step 3: Working with activity_main.xml file
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Create a new layout for each item of the CardStackView and name it item_spot.xml. Create a new drawable with the name gradient_bg.xml which will be used as a gradient in front of the image.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:background="@color/white"
android:orientation="vertical">
<com.yuyakaido.android.cardstackview.CardStackView
android:id="@+id/card_stack_view"
android:layout_width="match_parent"
android:layout_height="400dp"
android:padding="4dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
item_spot.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackground"
android:foreground="?attr/selectableItemBackground"
app:cardUseCompatPadding="true"
app:cardPreventCornerOverlap="false"
app:cardCornerRadius="8dp"
app:cardBackgroundColor="@android:color/white">
<ImageView
android:id="@+id/item_image"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="16dp"
android:background="@drawable/gradient_bg">
<TextView
android:id="@+id/item_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="@android:color/white"
android:textSize="26sp"/>
<TextView
android:id="@+id/item_city"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:textColor="@android:color/white"
android:textSize="20sp"/>
</LinearLayout>
<FrameLayout
android:id="@+id/top_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<FrameLayout
android:id="@+id/bottom_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</androidx.cardview.widget.CardView>
gradient_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="@android:color/transparent"
android:endColor="#88000000"
android:angle="270" />
<corners
android:bottomLeftRadius="8dp"
android:bottomRightRadius="8dp" />
</shape>
Step 4: Creating a modal class for storing our data
Navigate to the app > java > {package-name}, Right-click on it, New > Java/Kotlin class and name it as Spot.
Spot.java
package org.geeksforgeeks.demo;
// A simple class to hold information about a spot
public class Spot {
// Auto-incremented unique ID
private final long id;
// Name of the spot
private final String name;
// City where the spot is located
private final String city;
// Related URL
private final String url;
// Static counter to generate unique IDs
private static long counter = 0;
// Constructor
public Spot(String name, String city, String url) {
this.id = counter++;
this.name = name;
this.city = city;
this.url = url;
}
// Getters
public long getId() {
return id;
}
public String getName() {
return name;
}
public String getCity() {
return city;
}
public String getUrl() {
return url;
}
}
Spot.kt
package org.geeksforgeeks.demo
// A simple data class to hold information about a spot
data class Spot(
// Auto-incremented unique ID
val id: Long = counter++,
// Name of the spot
val name: String,
// City where the spot is located
val city: String,
// Related URL
val url: String
) {
companion object {
// Counter to generate unique IDs
private var counter = 0L
}
}
Step 5: Creating an adapter class
Now for setting data to each card present in the stack, we have to create our adapter class. Navigate to the app > java > {package-name}, Right-click on it, New > Java/Kotlin class and name it as CardStackAdapter and add the below code to it.
CardStackAdapter.java
package org.geeksforgeeks.demo;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import java.util.List;
// Adapter for binding Spot data to RecyclerView cards
public class CardStackAdapter extends RecyclerView.Adapter<CardStackAdapter.ViewHolder> {
private List<Spot> spots;
public CardStackAdapter(List<Spot> spots) {
this.spots = spots;
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_spot, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Spot spot = spots.get(position);
holder.name.setText(spot.getName());
holder.city.setText(spot.getCity());
Glide.with(holder.image.getContext())
.load(spot.getUrl())
.into(holder.image);
}
@Override
public int getItemCount() {
return spots != null ? spots.size() : 0;
}
// ViewHolder class to hold references to views
public static class ViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public TextView city;
public ImageView image;
public ViewHolder(View view) {
super(view);
name = view.findViewById(R.id.item_name);
city = view.findViewById(R.id.item_city);
image = view.findViewById(R.id.item_image);
}
}
}
CardStackAdapter.kt
package org.geeksforgeeks.demo
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
// Adapter for binding Spot data to RecyclerView cards
class CardStackAdapter(
private var spots: List<Spot> = emptyList()
) : RecyclerView.Adapter<CardStackAdapter.ViewHolder>() {
// Creates a new ViewHolder when needed
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val inflater = LayoutInflater.from(parent.context)
return ViewHolder(inflater.inflate(R.layout.item_spot, parent, false))
}
// Binds data to the ViewHolder
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val spot = spots[position]
holder.name.text = spot.name
holder.city.text = spot.city
Glide.with(holder.image)
.load(spot.url)
.into(holder.image)
}
// Returns the total number of items
override fun getItemCount(): Int {
return spots.size
}
// Holds references to the views in each item
class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val name: TextView = view.findViewById(R.id.item_name)
var city: TextView = view.findViewById(R.id.item_city)
var image: ImageView = view.findViewById(R.id.item_image)
}
}
Step 6: Working with the MainActivity file
Go to the MainActivity file and refer to the following code. Below is the code for the MainActivity file. Comments are added inside the code to understand the code in more detail.
MainActivity.java
package org.geeksforgeeks.demo;
import android.os.Bundle;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.DefaultItemAnimator;
import com.yuyakaido.android.cardstackview.*;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements CardStackListener {
private CardStackView cardStackView;
private CardStackLayoutManager manager;
private CardStackAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cardStackView = findViewById(R.id.card_stack_view);
manager = new CardStackLayoutManager(this, this);
adapter = new CardStackAdapter(createSpots());
setupCardStackView();
}
private void setupCardStackView() {
initialize();
}
private void initialize() {
manager.setStackFrom(StackFrom.None);
manager.setVisibleCount(3);
manager.setTranslationInterval(8.0f);
manager.setScaleInterval(0.95f);
manager.setSwipeThreshold(0.3f);
manager.setMaxDegree(20.0f);
manager.setDirections(Direction.HORIZONTAL);
manager.setCanScrollHorizontal(true);
manager.setCanScrollVertical(true);
manager.setSwipeableMethod(SwipeableMethod.AutomaticAndManual);
manager.setOverlayInterpolator(new LinearInterpolator());
cardStackView.setLayoutManager(manager);
cardStackView.setAdapter(adapter);
if (cardStackView.getItemAnimator() instanceof DefaultItemAnimator) {
((DefaultItemAnimator) cardStackView.getItemAnimator()).setSupportsChangeAnimations(false);
}
}
private List<Spot> createSpots() {
List<Spot> spots = new ArrayList<>();
spots.add(new Spot("Example", "Kyoto", "https://images.pexels.com/photos/8361426/pexels-photo-8361426.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"));
spots.add(new Spot("Example", "Kyoto", "https://images.pexels.com/photos/18301868/pexels-photo-18301868/free-photo-of-traveler-in-a-headscarf-with-a-backpack-on-the-subway-platform.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"));
spots.add(new Spot("Example", "Kyoto", "https://images.pexels.com/photos/30652095/pexels-photo-30652095/free-photo-of-elegant-woman-in-white-dress-outdoors.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"));
spots.add(new Spot("Example", "New York", "https://images.pexels.com/photos/30800337/pexels-photo-30800337/free-photo-of-playful-border-collie-enjoying-snowy-winter-day.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"));
spots.add(new Spot("Example", "New York", "https://images.pexels.com/photos/31102315/pexels-photo-31102315/free-photo-of-casa-batllo-architectural-detail-in-barcelona.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"));
spots.add(new Spot("Example", "New York", "https://images.pexels.com/photos/31049335/pexels-photo-31049335/free-photo-of-majestic-longhorn-cow-grazing-in-wisconsin-field.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"));
return spots;
}
@Override
public void onCardDragging(Direction direction, float ratio) {
// Optional: implement if needed
}
@Override
public void onCardSwiped(Direction direction) {
if (direction == Direction.Right) {
Toast.makeText(this, "Swiped right", Toast.LENGTH_SHORT).show();
} else if (direction == Direction.Left) {
Toast.makeText(this, "Swiped left", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onCardRewound() {
// Optional: implement if needed
}
@Override
public void onCardCanceled() {
// Optional: implement if needed
}
@Override
public void onCardAppeared(View view, int position) {
// Optional: implement if needed
}
@Override
public void onCardDisappeared(View view, int position) {
// Optional: implement if needed
}
}
MainActivity.kt
package org.geeksforgeeks.demo
import android.os.Bundle
import android.view.View
import android.view.animation.LinearInterpolator
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DefaultItemAnimator
import com.yuyakaido.android.cardstackview.*
class MainActivity : AppCompatActivity(), CardStackListener {
// Card stack view and related components
private lateinit var cardStackView: CardStackView
private lateinit var manager: CardStackLayoutManager
private lateinit var adapter: CardStackAdapter
// Called when the activity is created
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
cardStackView = findViewById(R.id.card_stack_view)
manager = CardStackLayoutManager(this, this)
adapter = CardStackAdapter(createSpots())
setupCardStackView()
}
// Called when a card is being dragged
override fun onCardDragging(direction: Direction, ratio: Float) {}
// Called when a card is swiped
override fun onCardSwiped(direction: Direction) {
if (direction == Direction.Right) {
Toast.makeText(this, "Swiped right", Toast.LENGTH_SHORT).show()
} else if (direction == Direction.Left) {
Toast.makeText(this, "Swiped left", Toast.LENGTH_SHORT).show()
}
}
// Called when a card is rewound
override fun onCardRewound() {}
// Called when a swipe is canceled
override fun onCardCanceled() {}
// Called when a card appears on screen
override fun onCardAppeared(view: View, position: Int) {}
// Called when a card disappears from screen
override fun onCardDisappeared(view: View, position: Int) {}
// Sets up the card stack view
private fun setupCardStackView() {
initialize()
}
// Initializes the card stack manager and adapter
private fun initialize() {
manager.setStackFrom(StackFrom.None)
manager.setVisibleCount(3)
manager.setTranslationInterval(8.0f)
manager.setScaleInterval(0.95f)
manager.setSwipeThreshold(0.3f)
manager.setMaxDegree(20.0f)
manager.setDirections(Direction.HORIZONTAL)
manager.setCanScrollHorizontal(true)
manager.setCanScrollVertical(true)
manager.setSwipeableMethod(SwipeableMethod.AutomaticAndManual)
manager.setOverlayInterpolator(LinearInterpolator())
cardStackView.layoutManager = manager
cardStackView.adapter = adapter
cardStackView.itemAnimator.apply {
if (this is DefaultItemAnimator) {
supportsChangeAnimations = false
}
}
}
// Creates a list of Spot objects to show in the cards
private fun createSpots(): List<Spot> {
val spots = ArrayList<Spot>()
spots.add(Spot(name = "Example", city = "Kyoto", url = "https://images.pexels.com/photos/8361426/pexels-photo-8361426.jpeg?auto=compress&cs=tinysrgb&w=1260&h=750&dpr=1"))
spots.add(Spot(name = "Example", city = "Kyoto", url = "https://images.pexels.com/photos/18301868/pexels-photo-18301868/free-photo-of-traveler-in-a-headscarf-with-a-backpack-on-the-subway-platform.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"))
spots.add(Spot(name = "Example", city = "Kyoto", url = "https://images.pexels.com/photos/30652095/pexels-photo-30652095/free-photo-of-elegant-woman-in-white-dress-outdoors.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"))
spots.add(Spot(name = "Example", city = "New York", url = "https://images.pexels.com/photos/30800337/pexels-photo-30800337/free-photo-of-playful-border-collie-enjoying-snowy-winter-day.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"))
spots.add(Spot(name = "Example", city = "New York", url = "https://images.pexels.com/photos/31102315/pexels-photo-31102315/free-photo-of-casa-batllo-architectural-detail-in-barcelona.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"))
spots.add(Spot(name = "Example", city = "New York", url = "https://images.pexels.com/photos/31049335/pexels-photo-31049335/free-photo-of-majestic-longhorn-cow-grazing-in-wisconsin-field.jpeg?auto=compress&cs=tinysrgb&w=600&lazy=load"))
return spots
}
}
Output:
Similar Reads
Spinner in Android with Example
Android Spinner is a view similar to the dropdown list which is used to select one option from the list of options. It provides an easy way to select one item from the list of items and it shows a dropdown list of all values when we click on it. The default value of the android spinner will be the c
4 min read
TextView in Android with Example
TextView is a simple widget that is seen in every android application. This widget is used to display simple text within the android application. We can add custom styling to the text that we have to show. In this article, we will take a look at How to create a simple Text View in an android applica
2 min read
ParticleView in Android with Examples
ParticleView is an animation library and animations help to gain the attention of the user so it is best to learn it. It is the custom Android view that helps to display a large number of fairies. [video loading="lazy" mp4="https://media.geeksforgeeks.org/wp-content/uploads/20240725161641/particlevi
2 min read
PhotoView in Android with Example
In this article, PhotoView is added to android. PhotoView aims to help produce an easily usable implementation of a zooming Android ImageView using multi-touch and double-tap. Besides that, it has many more features like it notifying the application when the user taps on the photo or when the displa
2 min read
Line Graph View in Android with Example
If you are looking for a view to represent some statistical data or looking for a UI for displaying a graph in your app then in this article we will take a look on creating a line graph view in our Android App using the GraphView library. What we are going to build in this article? We will be build
3 min read
LineAnimationView in Android with Example
LineAnimationView is an animation library that helps to gain the attention of the user. It is useful for creating very beautiful animation. In this animation, an object emerges from the bottom and goes to the top. Some useful features and applications of LineAnimationView are: Use this view where if
2 min read
SlidingDrawer in Android with Example
SlidingDrawer is a common requirement in android mobiles to view the content whenever needed by sliding horizontally as well as vertically. In this article, let us check out Sliding Drawer which is used to hide the content out from the screen and allows the user to drag a handle to bring the content
9 min read
NestedScrollView in Android with Example
NestedScrollView is an advanced version of ScrollView, that supports nested scrolling operations allowing it to act as both a parent and child. NestedScrollView is used when there is a need for a scrolling view insidee which view to scroll. Let's discuss a NestedScrollView in Android by taking an ex
3 min read
SimpleAdapter in Android with Example
In Android, whenever we want to bind some data which we get from any data source (e.g. ArrayList, HashMap, SQLite, etc.) with a UI component(e.g. ListView, GridView, etc.) then Adapter comes into the picture. Basically Adapter acts as a bridge between the UI component and data sources. Here Simple A
7 min read
Android ListView in Java with Example
A ListView in Android is a type of AdapterView that displays a vertically scrollable list of items, with each item positioned one below the other. Using an adapter, items are inserted into the list from an array or database efficiently. For displaying the items in the list method setAdaptor() is use
3 min read