Hay tantas aplicaciones que están presentes en Play Store que brindan detalles relacionados con diferentes libros dentro de ella. Book Library se considera una de las aplicaciones básicas que un principiante puede desarrollar para aprender algunos conceptos básicos dentro de Android, como el análisis JSON, el uso de la vista del reciclador y otros. En este artículo, crearemos una aplicación de biblioteca de libros simple para mostrar diferentes tipos de libros. Usaremos la API de Google Books para crear esta aplicación.
Nota : si está buscando crear una aplicación de biblioteca de libros usando la API de Google Books en Android usando Java. Consulte el siguiente artículo: Cómo crear una aplicación de biblioteca de libros con la API de Google Books en Android con Java
Implementación paso a paso
Paso 1: crea un nuevo proyecto en Android Studio
Para crear un nuevo proyecto en Android Studio, consulte Cómo crear/iniciar un nuevo proyecto en Android Studio . Tenga en cuenta que seleccione Kotlin como lenguaje de programación.
Paso 2: agregue la dependencia de Volley en sus archivos Gradle
Vaya a la aplicación > Gradle Scripts > archivo build.gradle y agregue la dependencia a continuación en la sección de dependencias.
implementation 'com.android.volley:volley:1.1.1' implementation 'com.squareup.picasso:picasso:2.71828'
Después de agregar las dependencias a continuación en su archivo Gradle, ahora sincronice su proyecto para instalar las dependencias.
Paso 3: Agregar permisos para Internet
Vaya a la aplicación > AndroidManifest.xml y agréguele los siguientes permisos.
XML
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Paso 4: trabajar con el archivo activity_main.xml
Vaya al archivo activity_main.xml y consulte el siguiente código. A continuación se muestra el código para el archivo activity_main.xml.
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>
Paso 5: crear una clase modal para almacenar nuestros datos desde la API
Para crear una nueva clase Modal. Vaya a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él y haga clic en Nuevo > clase Kotlin y asigne un nombre a nuestra clase java como BookRVModal y agréguele el siguiente código. Se agregan comentarios en el código para conocer con más detalle.
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 )
Paso 6: Cree un nuevo archivo de recursos de diseño
Vaya a la aplicación > res > diseño > haga clic con el botón derecho en > Nuevo > Archivo de recursos de diseño y nombre el archivo como book_item y agregue el siguiente código a este archivo.
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>
Paso 7: Crear una nueva actividad para mostrar nuestra información del libro en detalle
Vaya a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él y haga clic en Nuevo > Actividad > Seleccione Actividad vacía y asígnele el nombre BookDetailsActivity. Asegúrate de seleccionar Actividad vacía.
Paso 8: crear una clase de adaptador para configurar nuestros datos en el elemento de RecyclerView
Navegue a la aplicación > java > el nombre del paquete de su aplicación > haga clic con el botón derecho en él. Haga clic en Nuevo > clase Kotlin y asígnele el nombre BookRVAdapter y agréguele el siguiente código. Se agregan comentarios en el código para conocer con más detalle.
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) } }
Paso 9: Trabajar con el archivo activity_book_details.xml
Vaya al archivo app>res>layout>activity_book_details.cml y agréguele el siguiente código. Se agregan comentarios en el código para conocer en detalle.
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>
Paso 10: trabajar con el archivo BookDetailsActivity.kt
Vaya al archivo BookDetailsActivity.kt y consulte el siguiente código. A continuación se muestra el código del archivo BookDetailsActivity.kt. Se agregan comentarios dentro del código para comprender el código con más detalle.
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) } } }
Paso 11: trabajar con el archivo MainActivity.kt
Vaya al archivo MainActivity.kt y consulte el siguiente código. A continuación se muestra el código del archivo MainActivity.kt. Se agregan comentarios dentro del código para comprender el código con más detalle.
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 dislaying 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) } }
Ahora ejecute su aplicación para ver el resultado.
Producción:
Publicación traducida automáticamente
Artículo escrito por chaitanyamunje y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA