A Shayari app built in Android Studio consists of various Shayaries and categories of it using Firebase for database purposes, also you can add as many Shayaries and categories of it, indirectly to the firebases the user can access and also have share functionality on WhatsApp as well. A sample video is given below to get an idea about what we are going to do in this article.
Step-by-Step Implementation
Step 1: Create a New Project in Android Studio
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio.
Note: Select Kotlin as the programming language.
Step 2: Set up the development environment
Add View binding inside the android{} block in build.gradle(app) file
buildFeatures {
viewBinding = true
}Here is what the build.gradle(module: app) should look like
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.google.gms.google.services)
}
android {
namespace = "com.ishaanbhela.shayariapp"
compileSdk = 34
defaultConfig {
applicationId = "com.ishaanbhela.shayariapp"
minSdk = 26
targetSdk = 34
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}
buildFeatures {
viewBinding = true
}
buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
implementation(libs.firebase.firestore)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
}
Step 3: Create a new Firebase Project
Add Firebase Firestore dependency in build.gradle(app) file
You can also refer this article if you prefer using GUI. Adding Firebase to Android Application.
implementation("com.google.firebase:firebase-firestore:25.1.0")
implementation("com.google.firebase:firebase-firestore-ktx:25.1.0")Dont forget to activate Firebase Firestore inside the Firebase Console!
Step 4: Adding resources
We will be adding some colors inside the application. Head to app > res > values > colors.xml.
Write the following code in it:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="red">#ff0000</color>
<color name="orange">#FFA500</color>
</resources>
We will also be needing some icon images inside our Application
- Back icon
- Copy icon
- Share icon
- Hamburger Menu icon
- Whatsapp icon
You can find all the resources here: Resources
Refer this article to add images inside your project: How to add Images in the Android Project.
Step 5: Design the app’s user interface
Navigate to the app > res > layout > activity_main.xml and add the below code to that file. Below is the code for the activity_main.xml file.
This activity is to display the number of Categories of Shayaries available inside the Firestore database. It will display all the categories which users can select and see All the Shayaries inside that category.
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout
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:id="@+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="@color/red">
<ImageView
android:id="@+id/btnMenu"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:layout_marginStart="20dp"
android:backgroundTint="@color/white"
android:src="@drawable/ham"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="9.2"
android:layout_marginStart="10dp"
android:textStyle="bold"
android:text="Hindi Shayari"
android:textColor="@color/white"
android:textSize="20sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rcvCategory"
android:layout_below="@id/toolbar"/>
</RelativeLayout>
</androidx.drawerlayout.widget.DrawerLayout>
activity_start.xml
This is the launch activity of our Application. It will have a Start button which will lead to Main Activity, a Rating button one "More" Button.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/start"
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=".Start">
<LinearLayout
android:id="@+id/linearLayout"
android:layout_width="match_parent"
android:layout_height="45dp"
android:background="#D62828"
android:gravity="center_vertical"
android:orientation="horizontal"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textStyle="bold"
android:text="Hindi Shayari"
android:textColor="@color/white"
android:textSize="20sp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/linearLayout">
<TextView
android:id="@+id/btnStart"
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginEnd="20sp"
android:textStyle="bold"
android:gravity="center"
android:padding="15dp"
android:background="@color/orange"
android:text="Start"
android:textColor="@color/black"
android:textSize="20sp" />
<TextView
android:id="@+id/btnRate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="20sp"
android:background="@color/orange"
android:textStyle="bold"
android:gravity="center"
android:padding="15dp"
android:text="Rate"
android:textColor="@color/black"
android:textSize="20sp" />
<TextView
android:id="@+id/btnMore"
android:layout_width="match_parent"
android:layout_marginBottom="15dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="20sp"
android:background="@color/orange"
android:textStyle="bold"
android:gravity="center"
android:padding="15dp"
android:text="More"
android:textColor="@color/black"
android:textSize="20sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
activity_all_shayari.xml
After Selecting a particular Category from MainActivity, this activity will be shown which will contain all the shayaries of that particular category!
All these shayaries will be stored inside the Firestore database.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/allShayari"
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=".all_shayari">
<LinearLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:gravity="center_vertical"
android:background="@color/red">
<ImageView
android:id="@+id/btnBack"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8"
android:layout_marginStart="20dp"
android:backgroundTint="@color/white"
android:src="@drawable/back"/>
<TextView
android:id="@+id/catName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="9.2"
android:layout_marginStart="10dp"
android:textStyle="bold"
android:text="Hindi Shayari"
android:textColor="@color/white"
android:textSize="20sp" />
</LinearLayout>
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/toolbar"
android:id="@+id/rcvAllShayari"/>
</RelativeLayout>
item_category.xml
This is the layout for the recycler view inside activity_main.xml. It has a TextView which will contain a category name.
<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="10dp"
app:cardCornerRadius="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/item_txt"
android:layout_gravity="center"
android:fontFamily="@font/bold"
android:gravity="center"
android:text="Hindi Shayari"
android:textSize="25sp" />
</androidx.cardview.widget.CardView>
</LinearLayout>
item_shayari.xml
This is the layout for displaying Shayaries inside all_shayari_activity.xml. This layout contains A TextView to show Shayaries, a share icon, a copy icon and a whatsapp icon.
<?xml version="1.0" encoding="utf-8"?>
<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="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
app:cardCornerRadius="10dp">
<LinearLayout
android:id="@+id/mainBaground"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/itemShayari"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:fontFamily="@font/bold"
android:gravity="center"
android:text=""
android:textColor="@color/black"
android:textSize="22sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#80000000"
android:orientation="horizontal"
android:padding="10dp">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<LinearLayout
android:id="@+id/btnShare"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@drawable/btn_round_shape"
android:padding="7dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/ic_baseline_share_24" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<LinearLayout
android:id="@+id/btnCopy"
android:padding="7dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@drawable/btn_round_shape">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/ic_baseline_content_copy_24" />
</LinearLayout>
</FrameLayout>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
<LinearLayout
android:id="@+id/btnWhatsapp"
android:padding="7dp"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center"
android:background="@drawable/btn_round_shape">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@drawable/whatsapp" />
</LinearLayout>
</FrameLayout>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</RelativeLayout>
Step 5: Creating Adapters for the two Recycler Views
Adapters in RecyclerViews is a class which binds data with the layout inside the UI. The adapter acts as a bridge between the data source (such as a list or an array) and the RecyclerView's UI elements.
AllShayariAdapter.kt
package com.ishaanbhela.shayariapp
import android.content.ActivityNotFoundException
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context.CLIPBOARD_SERVICE
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.ishaanbhela.shayariapp.databinding.ItemShayariBinding
class AllShayariAdapter(
val allShayariActivity: all_shayari, val shayariList: ArrayList<ShayariModel>) : RecyclerView.Adapter<AllShayariAdapter.ShayariViewHolder>() {
class ShayariViewHolder(val binding: ItemShayariBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShayariViewHolder {
return ShayariViewHolder(
ItemShayariBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: ShayariViewHolder, position: Int) {
holder.binding.itemShayari.text = shayariList[position].data.toString()
holder.binding.btnCopy.setOnClickListener {
val clipboard: ClipboardManager? =
allShayariActivity.getSystemService(CLIPBOARD_SERVICE) as ClipboardManager?
val clip = ClipData.newPlainText("label", shayariList[position].data.toString())
clipboard?.setPrimaryClip(clip)
Toast.makeText(allShayariActivity,"Shayari Copied Successfully",Toast.LENGTH_SHORT).show()
}
holder.binding.btnShare.setOnClickListener {
try {
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.type = "text/plain"
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "My application name")
var shareMessage = "\n${shayariList[position].data}\n\n"
shareMessage =
"""
${shareMessage}https://play.google.com/store/apps/details?id=$%7BBuildConfig.APPLICATION_ID%7D
""".trimIndent()
shareIntent.putExtra(Intent.EXTRA_TEXT, shareMessage)
allShayariActivity.startActivity(Intent.createChooser(shareIntent, "choose one"))
} catch (e: Exception) {
//e.toString();
}
true
}
holder.binding.btnWhatsapp.setOnClickListener {
val whatsappIntent = Intent(Intent.ACTION_SEND)
whatsappIntent.type = "text/plain"
whatsappIntent.setPackage("com.whatsapp")
whatsappIntent.putExtra(Intent.EXTRA_TEXT, shayariList[position].data.toString())
try {
allShayariActivity.startActivity(whatsappIntent)
} catch (ex: ActivityNotFoundException) {
}
}
}
override fun getItemCount() = shayariList.size
}
package com.ishaanbhela.shayariapp
import android.content.Intent
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.ishaanbhela.shayariapp.databinding.ItemCategoryBinding
class CategoryAdapter(val mainActivity: MainActivity, val list: ArrayList<CategoryModel>) : RecyclerView.Adapter<CategoryAdapter.CatViewHolder>() {
class CatViewHolder(val binding: ItemCategoryBinding) : RecyclerView.ViewHolder(binding.root)
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CatViewHolder {
return CatViewHolder(
ItemCategoryBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: CatViewHolder, position: Int) {
holder.binding.itemTxt.text = list[position].name.toString()
holder.binding.root.setOnClickListener {
val intent = Intent(mainActivity, all_shayari::class.java)
intent.putExtra("id", list[position].id)
intent.putExtra("name", list[position].name)
mainActivity.startActivity(intent)
}
}
override fun getItemCount() = list.size
}
Step 6: Create a Model for Shayari
Data model classes are crucial as they give a proper structured data to RecyclerView Adapters and Firebase Firestore operations so that databinding and Database operations become easier
package com.note.shayariapp.Model
class CategoryModel(
val id: String? = null,
val name: String? = null
)
package com.note.shayariapp.Model
class ShayariModel(
val id: String? = null,
val data: String? = null
)
Step 7: Finally Write code in Activities
AllShayariActivity.kt
In this activity, we will be retrieving all the shayaries in a particular category that is provided to us through an Intent when a user selects a category from MainActivity.kt. This activity will handle displaying, sharing and copying of shayari.
package com.ishaanbhela.shayariapp
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.firestore.FirebaseFirestore
import com.ishaanbhela.shayariapp.databinding.ActivityAllShayariBinding
class all_shayari : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lateinit var binding: ActivityAllShayariBinding
lateinit var db: FirebaseFirestore
enableEdgeToEdge()
binding = ActivityAllShayariBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.allShayari)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
val name = intent.getStringExtra("name")
val id = intent.getStringExtra("id")
db = FirebaseFirestore.getInstance()
binding.btnBack.setOnClickListener {
onBackPressed()
}
binding.catName.text = name.toString()
db.collection("Shayari").document(id!!).collection("all")
.addSnapshotListener { value, error ->
val shayariList = arrayListOf<ShayariModel>()
val data = value?.toObjects(ShayariModel::class.java)
shayariList.addAll(data!!)
binding.rcvAllShayari.layoutManager = LinearLayoutManager(this)
binding.rcvAllShayari.adapter = AllShayariAdapter(this, shayariList)
}
}
}
MainActivity.kt
This activity will retrieve all the categories from Firestore and display it. Users can click on any category to see all the shayaries of that category.
package com.ishaanbhela.shayariapp
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.firebase.firestore.FirebaseFirestore
import com.ishaanbhela.shayariapp.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lateinit var binding: ActivityMainBinding
lateinit var db: FirebaseFirestore
enableEdgeToEdge()
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.drawerLayout)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
db = FirebaseFirestore.getInstance()
db.collection("Shayari").addSnapshotListener { value, error ->
val list = arrayListOf<CategoryModel>()
val data = value?.toObjects(CategoryModel::class.java)
list.addAll(data!!)
binding.rcvCategory.layoutManager = LinearLayoutManager(this)
binding.rcvCategory.adapter = CategoryAdapter(this, list)
}
}
override fun onBackPressed() {
super.onBackPressed()
}
}
StartActivity.kt
package com.ishaanbhela.shayariapp
import android.content.ActivityNotFoundException
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.Toast
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import com.ishaanbhela.shayariapp.databinding.ActivityStartBinding
class Start : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
lateinit var binding: ActivityStartBinding
enableEdgeToEdge()
binding = ActivityStartBinding.inflate(layoutInflater)
setContentView(binding.root)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.start)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
}
binding.btnStart.setOnClickListener {
startActivity(Intent(this, MainActivity::class.java))
}
binding.btnRate.setOnClickListener {
val uri = Uri.parse("market://details?id=$packageName")
val myAppLinkToMarket = Intent(Intent.ACTION_VIEW, uri)
try {
startActivity(myAppLinkToMarket)
} catch (e: ActivityNotFoundException) {
Toast.makeText(this, " unable to find market app", Toast.LENGTH_LONG).show()
}
}
binding.btnMore.setOnClickListener {
try {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("market://details?id=$packageName")
)
)
} catch (e: ActivityNotFoundException) {
startActivity(
Intent(
Intent.ACTION_VIEW,
Uri.parse("https://play.google.com/store/apps/details?id=$packageName")
)
)
}
}
}
}
Output:
Don't forget to populate your Database before testing!
Click Here to Access the Full Code for the Application