Android - Build a Book Library App using Kotlin
Last Updated :
17 Aug, 2022
There are so many apps that are present in the play store which provides details related to different books inside it. Book Library is considered one of the basic applications which a beginner can develop to learn some basic concepts within android such as JSON parsing, using recycler view, and others. In this article, we will be building a simple Book Library application to display different types of books. We will be using Google Books API for building this application.
Note: If you are looking to build a Book Library application using Google Books API in android using Java. Check out the following article: How to Build a Book Library App using Google Books API in Android using Java
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 that select Kotlin as the programming language.
Step 2: Add the dependency for Volley in your Gradle files
Navigate to the app > Gradle Scripts > build.gradle file and add the below dependency in the dependencies section.
implementation 'com.android.volley:volley:1.1.1'
implementation 'com.squareup.picasso:picasso:2.71828'
After adding the below dependencies in your Gradle file now sync your project to install dependencies.
Step 3: Adding permissions for the Internet
Navigate to the app > AndroidManifest.xml and add the below permissions to it.
XML
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Step 4: Working with the activity_main.xml file
Go to the activity_main.xml file and refer to the following code. Below is the code for the activity_main.xml file.
XML
<?xml version="1.0" encoding="utf-8"?>
<!--on below line we are creating a swipe to refresh layout-->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fillViewport="true"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:id="@+id/idLLsearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="5">
<!--edit text for getting the search
query for book from user-->
<EditText
android:id="@+id/idEdtSearchBooks"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4" />
<!--image button for our search button -->
<ImageButton
android:id="@+id/idBtnSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="@drawable/ic_search" />
</LinearLayout>
<!--recycler view for displaying our list of books-->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/idRVBooks"
android:layout_width="match_parent"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
android:layout_height="match_parent"
android:layout_below="@id/idLLsearch" />
<!--progressbar for displaying our loading indicator-->
<ProgressBar
android:id="@+id/idLoadingPB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone" />
</RelativeLayout>
Step 5: Creating a Modal Class for storing our data from the API
For creating a new Modal class. Navigate to the app > java > your app’s package name > Right-click on it and Click on New > Kotlin class and give a name to our java class as BookRVModal and add the below code to it. Comments are added in the code to get to know in more detail.
Kotlin
package com.gtappdevelopers.kotlingfgproject
data class BookRVModal(
// creating string, int and array list
// variables for our book details
var title: String,
var subtitle: String,
var authors: ArrayList<String>,
var publisher: String,
var publishedDate: String,
var description: String,
var pageCount: Int,
var thumbnail: String,
var previewLink: String,
var infoLink: String,
var buyLink: String
)
Step 6: Create a new layout resource file
Go to the app > res > layout > right-click > New > Layout Resource File and name the file as book_item and add the following code to this file.
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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_margin="5dp"
app:cardCornerRadius="5dp"
app:cardElevation="4dp">
<!--on below line we are creating a
linear layout for grid view item-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--on below line we are creating
a simple image view-->
<ImageView
android:id="@+id/idIVBook"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_margin="8dp"
android:padding="5dp"
android:scaleType="fitCenter"
android:src="@mipmap/ic_launcher" />
<!--on below line we are creating
a simple text view-->
<TextView
android:id="@+id/idTVBookName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:lines="2"
android:maxLines="2"
android:padding="4dp"
android:text="@string/app_name"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="12sp"
android:textStyle="bold"
tools:ignore="RtlCompat" />
<!--on below line we are creating
a text view for page number-->
<TextView
android:id="@+id/idTVBookPages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:text="Book Pages"
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="10sp" />
</LinearLayout>
</androidx.cardview.widget.CardView>
Step 7: Creating a new Activity for displaying our Book Info in detail
Navigate to the app > java > your app’s package name > Right-click on it and click on New > Activity > Select Empty Activity and name it as BookDetailsActivity. Make sure to select Empty Activity.
Step 8: Creating an Adapter class for setting our data to the item of RecyclerView
Navigate to the app > java > your app’s package name > Right-click on it Click on New > Kotlin class and name it as BookRVAdapter and add the below code to it. Comments are added in the code to get to know in more detail.
Kotlin
package com.gtappdevelopers.kotlingfgproject
import android.content.Context
import android.content.Intent
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.squareup.picasso.Picasso
class BookRVAdapter(
// on below line we are passing variables
// as course list and context
private var bookList: ArrayList<BookRVModal>,
private var ctx: Context
) : RecyclerView.Adapter<BookRVAdapter.BookViewHolder>() {
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): BookRVAdapter.BookViewHolder {
// this method is use to inflate the layout file
// which we have created for our recycler view.
// on below line we are inflating our layout file.
val itemView = LayoutInflater.from(parent.context).inflate(
R.layout.book_item,
parent, false
)
// at last we are returning our view holder
// class with our item View File.
return BookRVAdapter.BookViewHolder(itemView)
}
override fun onBindViewHolder(holder: BookRVAdapter.BookViewHolder, position: Int) {
val bookInfo = bookList.get(position)
// below line is use to set image from URL in our image view.
Picasso.get().load(bookInfo.thumbnail).into(holder.bookIV);
holder.bookTitleTV.text = bookInfo.title
holder.bookPagesTV.text = "Pages : " + bookInfo.pageCount
// below line is use to add on click listener for our item of recycler view.
holder.itemView.setOnClickListener {
// inside on click listener method we are calling a new activity
// and passing all the data of that item in next intent.
val i = Intent(ctx, BookDetailsActivity::class.java)
i.putExtra("title", bookInfo.title)
i.putExtra("subtitle", bookInfo.subtitle)
i.putExtra("authors", bookInfo.authors)
i.putExtra("publisher", bookInfo.publisher)
i.putExtra("publishedDate", bookInfo.publishedDate)
i.putExtra("description", bookInfo.description)
i.putExtra("pageCount", bookInfo.pageCount)
i.putExtra("thumbnail", bookInfo.thumbnail)
i.putExtra("previewLink", bookInfo.previewLink)
i.putExtra("infoLink", bookInfo.infoLink)
i.putExtra("buyLink", bookInfo.buyLink)
// after passing that data we are
// starting our new intent.
ctx.startActivity(i)
}
}
override fun getItemCount(): Int {
return bookList.size
}
class BookViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
// on below line we are initializing our
// course name text view and our image view.
val bookTitleTV: TextView = itemView.findViewById(R.id.idTVBookName)
val bookPagesTV: TextView = itemView.findViewById(R.id.idTVBookPages)
val bookIV: ImageView = itemView.findViewById(R.id.idIVBook)
}
}
Step 9: Working with the activity_book_details.xml file
Navigate to app>res>layout>activity_book_details.cml file and add the below code to it. Comments are added in the code to get to know in detail.
XML
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".BookDetailsActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!--Image view for displaying our book image-->
<ImageView
android:id="@+id/idIVbook"
android:layout_width="130dp"
android:layout_height="160dp"
android:layout_margin="18dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical">
<!--Text view for displaying book publisher-->
<TextView
android:id="@+id/idTVpublisher"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="4dp"
android:text="Publisher"
android:textColor="@color/black"
android:textSize="15sp" />
<!--text view for displaying number of pages of book-->
<TextView
android:id="@+id/idTVNoOfPages"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:padding="4dp"
android:text="Number of Pages"
android:textColor="@color/black"
android:textSize="15sp" />
<!--text view for displaying book publish date-->
<TextView
android:id="@+id/idTVPublishDate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:padding="4dp"
android:text="Publish Date"
android:textColor="@color/black"
android:textSize="15sp" />
</LinearLayout>
</LinearLayout>
<!--text view for displaying book title-->
<TextView
android:id="@+id/idTVTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="4dp"
android:text="title"
android:textColor="@color/black"
android:textSize="15sp" />
<!--text view for displaying book subtitle-->
<TextView
android:id="@+id/idTVSubTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="4dp"
android:text="subtitle"
android:textColor="@color/black"
android:textSize="12sp" />
<!--text view for displaying book description-->
<TextView
android:id="@+id/idTVDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:padding="4dp"
android:text="description"
android:textColor="@color/black"
android:textSize="12sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:orientation="horizontal"
android:weightSum="2">
<!--button for displaying book preview-->
<Button
android:id="@+id/idBtnPreview"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:text="Preview"
android:textAllCaps="false" />
<!--button for opening buying page of the book-->
<Button
android:id="@+id/idBtnBuy"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="4dp"
android:layout_weight="1"
android:text="Buy"
android:textAllCaps="false" />
</LinearLayout>
</LinearLayout>
</ScrollView>
Step 10: Working with the BookDetailsActivity.kt file
Go to the BookDetailsActivity.kt file and refer to the following code. Below is the code for the BookDetailsActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
package com.gtappdevelopers.kotlingfgproject
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.squareup.picasso.Picasso
class BookDetailsActivity : AppCompatActivity() {
// creating variables for strings,text view,
// image views and button.
lateinit var titleTV: TextView
lateinit var subtitleTV: TextView
lateinit var publisherTV: TextView
lateinit var descTV: TextView
lateinit var pageTV: TextView
lateinit var publisherDateTV: TextView
lateinit var previewBtn: Button
lateinit var buyBtn: Button
lateinit var bookIV: ImageView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_book_details)
// initializing our variables.
titleTV = findViewById(R.id.idTVTitle)
subtitleTV = findViewById(R.id.idTVSubTitle)
publisherTV = findViewById(R.id.idTVpublisher)
descTV = findViewById(R.id.idTVDescription)
pageTV = findViewById(R.id.idTVNoOfPages)
publisherDateTV = findViewById(R.id.idTVPublishDate)
previewBtn = findViewById(R.id.idBtnPreview)
buyBtn = findViewById(R.id.idBtnBuy)
bookIV = findViewById(R.id.idIVbook)
// getting the data which we have passed from our adapter class.
val title = getIntent().getStringExtra("title")
val subtitle = getIntent().getStringExtra("subtitle")
val publisher = getIntent().getStringExtra("publisher")
val publishedDate = getIntent().getStringExtra("publishedDate")
val description = getIntent().getStringExtra("description")
val pageCount = getIntent().getIntExtra("pageCount", 0)
val thumbnail = getIntent().getStringExtra("thumbnail")
val previewLink = getIntent().getStringExtra("previewLink")
val infoLink = getIntent().getStringExtra("infoLink")
val buyLink = getIntent().getStringExtra("buyLink")
// after getting the data we are setting
// that data to our text views and image view.
titleTV.setText(title)
subtitleTV.setText(subtitle)
publisherTV.setText(publisher)
publisherDateTV.setText("Published On : " + publishedDate)
descTV.setText(description)
pageTV.setText("No Of Pages : " + pageCount)
Picasso.get().load(thumbnail).into(bookIV)
// adding on click listener for our preview button.
previewBtn.setOnClickListener {
if (previewLink.isNullOrEmpty()) {
// below toast message is displayed
// when preview link is not present.
Toast.makeText(
this@BookDetailsActivity,
"No preview Link present",
Toast.LENGTH_SHORT
)
.show()
}
// if the link is present we are opening
// that link via an intent.
val uri: Uri = Uri.parse(previewLink)
val i = Intent(Intent.ACTION_VIEW, uri)
startActivity(i)
}
// adding click listener for buy button
buyBtn.setOnClickListener {
if (buyLink.isNullOrEmpty()) {
// below toast message is displaying
// when buy link is empty.
Toast.makeText(
this@BookDetailsActivity,
"No buy page present for this book",
Toast.LENGTH_SHORT
).show()
}
// if the link is present we are opening
// the link via an intent.
val uri = Uri.parse(buyLink)
val i = Intent(Intent.ACTION_VIEW, uri)
startActivity(i)
}
}
}
Step 11: Working with the MainActivity.kt file
Go to the MainActivity.kt file and refer to the following code. Below is the code for the MainActivity.kt file. Comments are added inside the code to understand the code in more detail.
Kotlin
package com.gtappdevelopers.kotlingfgproject
import android.os.Bundle
import android.view.View
import android.widget.EditText
import android.widget.ImageButton
import android.widget.ProgressBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.RequestQueue
import com.android.volley.toolbox.JsonObjectRequest
import com.android.volley.toolbox.Volley
class MainActivity : AppCompatActivity() {
// on below line we are creating variables.
lateinit var mRequestQueue: RequestQueue
lateinit var booksList: ArrayList<BookRVModal>
lateinit var loadingPB: ProgressBar
lateinit var searchEdt: EditText
lateinit var searchBtn: ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// on below line we are initializing
// our variable with their ids.
loadingPB = findViewById(R.id.idLoadingPB)
searchEdt = findViewById(R.id.idEdtSearchBooks)
searchBtn = findViewById(R.id.idBtnSearch)
// adding click listener for search button
searchBtn.setOnClickListener {
loadingPB.visibility = View.VISIBLE
// checking if our edittext field is empty or not.
if (searchEdt.text.toString().isNullOrEmpty()) {
searchEdt.setError("Please enter search query")
}
// if the search query is not empty then we are
// calling get book info method to load all
// the books from the API.
getBooksData(searchEdt.getText().toString());
}
}
private fun getBooksData(searchQuery: String) {
// creating a new array list.
booksList = ArrayList()
// below line is use to initialize
// the variable for our request queue.
mRequestQueue = Volley.newRequestQueue(this@MainActivity)
// below line is use to clear cache this
// will be use when our data is being updated.
mRequestQueue.cache.clear()
// below is the url for getting data from API in json format.
val url = "https://www.googleapis.com/books/v1/volumes?q=$searchQuery"
// below line we are creating a new request queue.
val queue = Volley.newRequestQueue(this@MainActivity)
// on below line we are creating a variable for request
// and initializing it with json object request
val request = JsonObjectRequest(Request.Method.GET, url, null, { response ->
loadingPB.setVisibility(View.GONE);
// inside on response method we are extracting all our json data.
try {
val itemsArray = response.getJSONArray("items")
for (i in 0 until itemsArray.length()) {
val itemsObj = itemsArray.getJSONObject(i)
val volumeObj = itemsObj.getJSONObject("volumeInfo")
val title = volumeObj.optString("title")
val subtitle = volumeObj.optString("subtitle")
val authorsArray = volumeObj.getJSONArray("authors")
val publisher = volumeObj.optString("publisher")
val publishedDate = volumeObj.optString("publishedDate")
val description = volumeObj.optString("description")
val pageCount = volumeObj.optInt("pageCount")
val imageLinks = volumeObj.optJSONObject("imageLinks")
val thumbnail = imageLinks.optString("thumbnail")
val previewLink = volumeObj.optString("previewLink")
val infoLink = volumeObj.optString("infoLink")
val saleInfoObj = itemsObj.optJSONObject("saleInfo")
val buyLink = saleInfoObj.optString("buyLink")
val authorsArrayList: ArrayList<String> = ArrayList()
if (authorsArray.length() != 0) {
for (j in 0 until authorsArray.length()) {
authorsArrayList.add(authorsArray.optString(i))
}
}
// after extracting all the data we are
// saving this data in our modal class.
val bookInfo = BookRVModal(
title,
subtitle,
authorsArrayList,
publisher,
publishedDate,
description,
pageCount,
thumbnail,
previewLink,
infoLink,
buyLink
)
// below line is use to pass our modal
// class in our array list.
booksList.add(bookInfo)
// below line is use to pass our
// array list in adapter class.
val adapter = BookRVAdapter(booksList, this@MainActivity)
// below line is use to add linear layout
// manager for our recycler view.
val layoutManager = GridLayoutManager(this, 3)
val mRecyclerView = findViewById<RecyclerView>(R.id.idRVBooks) as RecyclerView
// in below line we are setting layout manager and
// adapter to our recycler view.
mRecyclerView.layoutManager = layoutManager
mRecyclerView.adapter = adapter
}
} catch (e: Exception) {
e.printStackTrace()
}
}, { error ->
// in this case we are simply displaying a toast message.
Toast.makeText(this@MainActivity, "No books found..", Toast.LENGTH_SHORT)
.show()
})
// at last we are adding our
// request to our queue.
queue.add(request)
}
}
Now run your application to see the output of it.
Output:
Similar Reads
How to Build a Book Library App using Google Books API in Android?
If you are looking for building a book library app and you want to load a huge data of books then for adding this feature, you have to use a simple API which is provided by Google, and of course, it's free. In this article, we will take a look at the implementation of this API in our Android App. Wh
15+ min read
How to Build a Simple Torch App in Android using Kotlin?
Torch Application is a very basic application that every beginner level android developer should definitely try to build while learning Android. In this article, we will be creating an application in which we will simply display a toggle button to switch on and switch off the torch. Note: If you are
4 min read
How to Build a Simple Music Player App using Android Kotlin
This is a very simple app suitable for beginners to learn the concepts. The following things you will learn in this article: Implementing MediaPlayer class and using its methods like pause, play and stop. Using external files ( images, audio, etc ) in our project.Building the interface of our Music
5 min read
How to Build a QR Code Android App using Firebase?
QR (Quick Response) code is a type of two-dimensional barcode that contains information encoded in a pattern of black and white squares. It was first developed in 1994 by a company named Denso Wave. Qr codes can be scanned by a smartphone or a dedicated QR code scanner, which uses the device's camer
6 min read
Play Audio From URL in Android using Kotlin
Many applications want to add different types of audio files to their android applications. These audio files are played using a media player within the android application. We can play audio files within the android application from different sources by playing audio from a web URL or by simply add
4 min read
How to Build a Bitcoin Tracker Android App?
In this article, we will be building a Bitcoin Tracker Project using Java/Kotlin and XML in Android. The application will display the current rates of Bitcoin in different countries using Bitcoin API. There are many free APIs available and for this project, we will be using API by Coinlayer. The API
7 min read
How to Use Dagger Library in Android App?
When we create a new Android Project, eventually we start accumulating different-different dependencies to get certain functionalities, but over time managing them becomes cumbersome, thus an injection framework like Dagger comes into play. However, setting up an injection service like Dagger requir
5 min read
How to Add RangeSeekbar in Android Using Kotlin?
In this article, Â RangeSeekbar is implemented in an application in android. Android Seekbar is a type of progress bar. We can drag the seekbar from left to right and vice versa and hence changes the current progress. Here we use the RangeSeekbar library to add custom seekbar in our app. This library
2 min read
Build a Recipe App using MVVM Architecture with Kotlin in Android
In this article, we will make a recipe app that displays a list of Italian recipes using the retrofit library and MVVM architecture. Model â View â ViewModel (MVVM) is the industry-recognized software architecture pattern that overcomes all drawbacks of MVP and MVC design patterns. MVVM suggests sep
8 min read
How to Build a Sensor App in Android?
Android mobile phones have sensors, so we can perform various functions like Controlling screen brightness, Monitoring acceleration along a single axis, Motion detection, etc. In this article, we will be building an application that will determine the intensity of light in the room with the help of
5 min read