En este artículo, vamos a crear una aplicación de comestibles en Android usando Android Studio. Muchas veces nos olvidamos de comprar cosas que queremos comprar, después de todo, no podemos recordar todos los artículos, por lo que con la ayuda de esta aplicación, puede anotar los artículos de abarrotes que va a comprar, haciendo esto no puedes olvidar ningún artículo que quieras comprar. qué
En este proyecto, usamos MVVM (Model View ViewModel) para patrones arquitectónicos, Room para base de datos, Coroutines y RecyclerView para mostrar la lista de elementos. Antes de saltar al proyecto, entendamos estos términos.
MVVM (Modelo Vista VistaModelo)
La arquitectura MVVM en Android se utiliza para dar estructura al código del proyecto y comprender el código fácilmente. MVVM es un patrón de diseño arquitectónico en android. MVVM trata las clases de actividad y los archivos XML como vista. Este patrón de diseño separa completamente la interfaz de usuario de su lógica. Aquí hay una imagen para entender rápidamente MVVM.
Después de ver esta imagen, si no entiende cómo funcionará, no se preocupe, escribiremos el código y lo entenderemos completamente.
Base de datos de habitaciones
La biblioteca de persistencia de habitaciones es una biblioteca de administración de base de datos y se utiliza para almacenar los datos de aplicaciones como el nombre del artículo de comestibles, la cantidad de artículos de comestibles y el precio de los artículos de comestibles. Room es una capa de cobertura en SQLite que ayuda a realizar fácilmente la operación en la base de datos.
RecycleView
RecyclerView es un contenedor y se usa para mostrar la recopilación de datos en una gran cantidad de conjuntos de datos que se pueden desplazar de manera muy efectiva manteniendo un número limitado de vistas.
corrutinas
Las corrutinas son un subproceso liviano, usamos una corrutina para realizar una operación en otros subprocesos, por lo que nuestro subproceso principal no se bloquea y nuestra aplicación no falla.
Implementación paso a paso
Paso 1: Crear un nuevo proyecto
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: antes de ir a la sección de codificación, primero debe hacer una tarea previa
Antes de ir a la parte de codificación, primero agregue estas bibliotecas en su archivo gradle y también aplique el complemento como ‘kotlin-kapt’. Para agregar esta biblioteca, vaya a Gradle Scripts > build.gradle(Module:app).
def habitación_versión = “2.2.1”
def ciclo_de_vida_versión = “2.0.0”
// Sala y Componentes Arquitectónicos
implementación “androidx.room:room-runtime:$room_version”
implementación “androidx.legacy:legacy-support-v4:1.0.0”
implementación ‘androidx.lifecycle:lifecycle-extensions:2.1.0’
implementación ‘androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0’
implementación “androidx.room:room-ktx:2.2.1”
kapt «androidx.room:room-compiler:$room_version»
// Corrutinas
implementación ‘org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0’
implementación “org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0”
// Nuevo diseño de materiales
implementación “com.google.android.material:material:1.0.0”
// Ver modelo
implementación «androidx.lifecycle:lifecycle-extensions:$lifecycle_version»
implementación «androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version»
kapt «androidx.lifecycle:lifecycle-compiler:$lifecycle_version»
A continuación se muestra el código completo para el archivo build.gradle(:app) .
Kotlin
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion 29 buildToolsVersion "30.0.3" defaultConfig { applicationId "com.example.grocerylist" minSdkVersion 16 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility = 1.8 targetCompatibility = 1.8 } kotlinOptions { jvmTarget = "1.8" } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.0.2' implementation 'androidx.core:core-ktx:1.0.2' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' def room_version = "2.2.1" def lifecycle_version = "2.0.0" // Room and Architectural Components implementation "androidx.room:room-runtime:$room_version" implementation "androidx.legacy:legacy-support-v4:1.0.0" implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0' implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.1.0' implementation "androidx.room:room-ktx:2.2.1" kapt "androidx.room:room-compiler:$room_version" // Coroutines implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0" // New Material Design implementation "com.google.android.material:material:1.0.0" // ViewModel implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version" kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version" }
A continuación se muestra el código del archivo strings.xml . Aquí hemos añadido las strings necesarias que vamos a utilizar en nuestro proyecto.
XML
<resources> <string name="app_name">Fresh Basket</string> <!-- TODO: Remove or change this placeholder text --> <string name="hello_blank_fragment">Hello blank fragment</string> <string name="itemName">Banana</string> <string name="itemQuantity">35</string> <string name="itemPrice">250Rs</string> <string name="totalCost">20</string> <string name="totalCostTitle">Total Cost</string> <string name="title">Add Items to your cart</string> <string name="etItem">Item</string> <string name="etQuantity">Quantity</string> <string name="etPrice">Price</string> <string name="save">Save</string> <string name="cancel">Cancel</string> </resources>
A continuación se muestra el código para el archivo colors.xml . Aquí hemos añadido los colores necesarios que vamos a utilizar en nuestro proyecto.
XML
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="colorPrimary">#0AD042</color> <color name="colorPrimaryDark">#03551A</color> <color name="colorAccent">#03DAC5</color> <color name="black">#000000</color> <color name="white">#ffffff</color> </resources>
Paso 3: implementar la base de datos de salas
a) Clase de entidades
La clase de entidades contiene todas las columnas de la base de datos y debe anotarse con @Entity(tablename = “Nombre de la tabla”). La clase de entidad es una clase de datos. Y la anotación de información @Column se usa para ingresar el nombre de la variable de columna y el tipo de datos. También agregaremos la clave principal para el incremento automático. Vaya a aplicación > java > com.example.nombre-aplicación. Haga clic con el botón derecho en com.example.application-name, vaya a nuevo y cree un archivo/clase Kotlin y nombre el archivo como GroceryEntities . Vea el código a continuación para comprenderlo e implementarlo por completo.
Kotlin
package com.example.grocerylist.Database.Entity import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.PrimaryKey // This is a data class which store data. // Entities class create a table in database, // in our database we will create three column @Entity(tableName = "grocery_items") data class GroceryItems( // create itemName variable to // store grocery items. @ColumnInfo(name = "itemName") var itemName: String, // create itemQuantity variable // to store grocery quantity. @ColumnInfo(name = "itemQuantity") var itemQuantity: Int, // create itemPrice variable to // store grocery price. @ColumnInfo(name = "itemPrice") var itemPrice: Int ) { // Primary key is a unique key // for different database. @PrimaryKey(autoGenerate = true) var id: Int? = null }
b) Interfaz Dao
El Dao es una interfaz en la que creamos todas las funciones que queremos implementar en la base de datos. Esta interfaz también anotó con @Dao. Ahora crearemos una función usando la función de suspensión, que es una función de rutinas. Aquí creamos tres funciones, primero es la función de inserción para insertar elementos en la base de datos y anotados con @Insert, segundo es para eliminar elementos de la base de datos anotados con @Delete y tercero es para obtener todos los elementos anotados con @Query. Vaya a la aplicación > java > com.example.application-name . Haga clic con el botón derecho en com.example.application-name, vaya a nuevo y cree el archivo/clase de Kotlin y nombre el archivo como GroceryDao . Vea el código a continuación para implementar.
Kotlin
package com.example.grocerylist.Database import androidx.lifecycle.LiveData import androidx.room.* import com.example.grocerylist.Database.Entity.GroceryItems // This class is used to create // function for database. @Dao interface GroceryDao { // Insert function is used to // insert data in database. @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun insert(item: GroceryItems) // Delete function is used to // delete data in database. @Delete suspend fun delete(item: GroceryItems) // getAllGroceryItems function is used to get // all the data of database. @Query("SELECT * FROM grocery_items") fun getAllGroceryItems(): LiveData<List<GroceryItems>> }
c) Clase de base de datos
Clase de base de datos anotada con @Database(entities = [Name of Entity class.class], version = 1) estas entidades son la array de entidades que enumera todas las entidades de datos asociadas con la base de datos y la versión muestra la versión actual de la base de datos. Esta clase de base de datos hereda de la clase Room Database. En la clase GroceryDatabase crearemos un método abstracto para obtener una instancia de DAO y usaremos este método desde la instancia de DAO para interactuar con la base de datos. Vea el siguiente código para implementar. Vaya a la aplicación > java > com.example.application-name . Haga clic con el botón derecho en com.example.application-name, vaya a new y cree el archivo/clase de Kotlin como GroceryDatabase . Vea el código a continuación para implementar.
Kotlin
package com.example.grocerylist.Database import android.content.Context import androidx.room.Database import androidx.room.Room import androidx.room.RoomDatabase import com.example.grocerylist.Database.Entity.GroceryItems @Database(entities = [GroceryItems::class], version = 1) abstract class GroceryDatabase : RoomDatabase() { abstract fun getGroceryDao(): GroceryDao companion object { @Volatile private var instance: GroceryDatabase? = null private val LOCK = Any() operator fun invoke(context: Context) = instance ?: synchronized(LOCK) { instance ?: createDatabase(context).also { instance = it } } private fun createDatabase(context: Context) = Room.databaseBuilder(context.applicationContext, GroceryDatabase::class.java, "GroceryDatabase.db").build() } }
Paso 4: Ahora implementaremos la estructura arquitectónica en la aplicación
a) Clase de repositorio
El repositorio es una de las estructuras de diseño. La clase de repositorio proporciona los datos a la clase ViewModel y luego la clase ViewModel usa esos datos para las Vistas. El repositorio elegirá los datos apropiados localmente o en la red. Aquí, en nuestro depósito de comestibles, los datos de clase se obtienen localmente de la base de datos de habitaciones. Agregaremos valor de constructor al crear una instancia de la base de datos y almacenarla en la variable db en la clase Grocery Repository. Vaya a la aplicación > java > com.example.application-name . Haga clic con el botón derecho en com.example.application-name, vaya a new y cree el archivo/clase de Kotlin como GroceryRepository . Vea el código a continuación para implementar.
Kotlin
package com.example.grocerylist.Database import com.example.grocerylist.Database.Entity.GroceryItems class GroceryRepository(private val db: GroceryDatabase) { suspend fun insert(item: GroceryItems) = db.getGroceryDao().insert(item) suspend fun delete(item: GroceryItems) = db.getGroceryDao().delete(item) fun allGroceryItems() = db.getGroceryDao().getAllGroceryItems() }
Ve a app > java > com.example.application-name . Haga clic derecho en com.example.application-name, vaya a nuevo y cree un nuevo paquete llamado UI y luego haga clic derecho en el paquete UI y cree un archivo/clase de Kotlin. Vea el código a continuación para implementar.
b) clase de modelo de vista
Clase ViewModel utilizada como interfaz entre View y Data. La clase Grocery View Model se hereda de la clase View Model y pasaremos el valor del constructor al crear una variable de instancia de la clase Repository y almacenarla en la variable del repositorio. A medida que pasamos el constructor en View Model, tenemos que crear otra clase que sea una clase Factory View Model. Vaya a app > java > com.example.application-name > UI . Haga clic con el botón derecho en el paquete de UI y cree un archivo/clase de Kotlin y nombre el archivo como GroceryViewModel . Vea el siguiente código.
Kotlin
package com.example.grocerylist.UI import androidx.lifecycle.ViewModel import com.example.grocerylist.Database.Entity.GroceryItems import com.example.grocerylist.Database.GroceryRepository import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch class GroceryViewModel(private val repository: GroceryRepository) : ViewModel() { // In coroutines thread insert item in insert function. fun insert(item: GroceryItems) = GlobalScope.launch { repository.insert(item) } // In coroutines thread delete item in delete function. fun delete(item: GroceryItems) = GlobalScope.launch { repository.delete(item) } //Here we initialized allGroceryItems function with repository fun allGroceryItems() = repository.allGroceryItems() }
c) clase de modelo de vista de fábrica
Heredaremos la clase Grocery ViewModel Factory de ViewModelProvider.NewInstanceFactory y nuevamente pasaremos el valor del constructor creando una variable de instancia de Grocery Repository y devolveremos GroceryViewModel (repositorio). Vaya a la aplicación > java > com.example.application-name > UI . Haga clic con el botón derecho en el paquete de la interfaz de usuario y cree un nombre de clase/archivo Kotlin GroceryViewModelFactory . Vea el siguiente código para entender.
Kotlin
package com.example.grocerylist.UI import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import com.example.grocerylist.Database.GroceryRepository class GroceryViewModelFactory(private val repository: GroceryRepository):ViewModelProvider.NewInstanceFactory() { override fun <T : ViewModel?> create(modelClass: Class<T>): T { return GroceryViewModel(repository) as T } }
Paso 5: ahora pasemos a la parte de la interfaz de usuario
En el archivo activity_main.xml , agregaremos dos ImageView , RecyclerView y Button después de hacer clic en este botón, se abre un cuadro de diálogo y en ese cuadro de diálogo el usuario puede ingresar el nombre del artículo, la cantidad del artículo y el precio del artículo. Consulte el siguiente código.
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="#ffffff" android:orientation="vertical" tools:context=".UI.MainActivity"> <!-- To create a app bar with logo image. --> <ImageView android:id="@+id/imageView2" android:layout_width="match_parent" android:layout_height="wrap_content" android:src="@drawable/logo" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" /> <!-- In this image view we will add a title image --> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="35dp" android:src="@drawable/title" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.497" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView2" app:layout_constraintVertical_bias="0.0" /> <!-- Recycler View to display list --> <androidx.recyclerview.widget.RecyclerView android:id="@+id/rvList" android:layout_width="match_parent" android:layout_height="470dp" android:background="@color/white" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView" app:layout_constraintVertical_bias="1.0"> </androidx.recyclerview.widget.RecyclerView> <!-- This button is used to open dialog box in which user can enter grocery items --> <Button android:id="@+id/btnAdd" android:layout_width="60dp" android:layout_height="wrap_content" android:background="@drawable/button" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.954" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView" app:layout_constraintVertical_bias="0.969" /> </androidx.constraintlayout.widget.ConstraintLayout>
Salida de código XML:
Paso 6: implementemos RecyclerView . Ahora codificaremos la parte de la interfaz de usuario de la fila en la lista. Vaya a aplicación > res > diseño . Haga clic con el botón derecho en el diseño, vaya a nuevo y luego agregue un archivo de recursos de diseño y asígnele el nombre de adaptador de comestibles . Consulte el código XML del archivo Grooveadapter.xml .
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" android:layout_width="match_parent" android:layout_height="125dp" android:background="@drawable/adapter1"> <!-- To display item name in recycler view --> <TextView android:id="@+id/txtItemName" android:layout_width="0dp" android:layout_height="53dp" android:layout_marginTop="16dp" android:layout_marginEnd="15dp" android:layout_marginRight="15dp" android:layout_marginBottom="17dp" android:fontFamily="@font/rokkitt" android:text="@string/itemName" android:textColor="@color/white" android:textSize="35sp" app:layout_constraintBottom_toTopOf="@+id/txtTotalCostTitle" app:layout_constraintEnd_toStartOf="@+id/txtItemQuantity" app:layout_constraintStart_toEndOf="@+id/cbItemCheck" app:layout_constraintTop_toTopOf="parent" /> <!-- To display item quantity --> <TextView android:id="@+id/txtItemQuantity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="34dp" android:layout_marginRight="34dp" android:layout_marginBottom="9dp" android:text="@string/itemQuantity" android:textColor="@color/white" android:textSize="25sp" app:layout_constraintBottom_toBottomOf="@+id/txtItemName" app:layout_constraintEnd_toStartOf="@+id/txtItemPrice" app:layout_constraintStart_toEndOf="@+id/txtItemName" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="1.0" /> <!-- To display item price --> <TextView android:id="@+id/txtItemPrice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="26dp" android:layout_marginEnd="22dp" android:layout_marginRight="22dp" android:layout_marginBottom="26dp" android:text="@string/itemPrice" android:textColor="@color/white" android:textSize="25sp" android:textStyle="bold" app:layout_constraintBottom_toTopOf="@+id/txtItemTotalCost" app:layout_constraintEnd_toStartOf="@+id/ibDelete" app:layout_constraintStart_toEndOf="@+id/txtItemQuantity" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.0" /> <CheckBox android:id="@+id/cbItemCheck" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="29dp" android:layout_marginLeft="29dp" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:background="@color/white" android:shadowColor="@color/black" app:layout_constraintBaseline_toBaselineOf="@+id/txtItemName" app:layout_constraintEnd_toStartOf="@+id/txtItemName" app:layout_constraintStart_toStartOf="parent" /> <!-- This button is used to delete grocery item --> <ImageButton android:id="@+id/ibDelete" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="26dp" android:layout_marginRight="26dp" android:background="@color/black" android:src="@drawable/ic_action_delete" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/txtItemPrice" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.257" /> <!-- To display total cost of grocery items --> <TextView android:id="@+id/txtItemTotalCost" android:layout_width="100dp" android:layout_height="60dp" android:background="@drawable/adapter2" android:padding="8dp" android:paddingLeft="12dp" android:text="@string/totalCost" android:textSize="30sp" android:textStyle="bold" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/txtTotalCostTitle" app:layout_constraintTop_toTopOf="@+id/txtTotalCostTitle" app:layout_constraintVertical_bias="0.875" /> <!-- This text view is used to add statement for total cost --> <TextView android:id="@+id/txtTotalCostTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="77dp" android:layout_marginLeft="77dp" android:layout_marginEnd="149dp" android:layout_marginRight="149dp" android:layout_marginBottom="16dp" android:text="@string/totalCostTitle" android:textColor="@color/white" android:textSize="20dp" android:visibility="invisible" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/txtItemTotalCost" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Salida de código XML:
Codificaremos la clase de adaptador para la vista del reciclador. En la clase Grocery Adapter, agregaremos el valor del constructor al almacenar la clase de entidades como una lista en la variable de lista y crearemos una instancia del modelo de vista. En Grocery Adapter anularemos tres funciones: onCreateViewHolder, getItemCount y onbindViewHolder, también crearemos una clase interna llamada titular de vista de supermercado. Vaya a la aplicación > java > com.example.application-name . Haga clic con el botón derecho en com.example.application-name, vaya a nuevo y cree un nuevo paquete llamado Adapter y luego haga clic con el botón derecho en el paquete Adapter y cree un nombre de clase/archivo Kotlin GroceryAdapter . Vea el siguiente código.
Kotlin
package com.example.grocerylist.Adapter import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import com.example.grocerylist.Database.Entity.GroceryItems import com.example.grocerylist.R import com.example.grocerylist.UI.GroceryViewModel import kotlinx.android.synthetic.main.groceryadapter.view.* class GroceryAdapter(var list: List<GroceryItems>, val viewModel: GroceryViewModel) : RecyclerView.Adapter<GroceryAdapter.GroceryViewHolder>() { // In this function we will add our groceryadapter.xml to kotlin class override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GroceryViewHolder { val view = LayoutInflater.from(parent.context).inflate(R.layout.groceryadapter, parent, false) return GroceryViewHolder(view) } // This function is used to return total number of size of list. override fun getItemCount(): Int { return list.size } // In onBindViewHolder we will bind our itemViews with adapter override fun onBindViewHolder(holder: GroceryViewHolder, position: Int) { var currentPosition = list[position] holder.itemView.txtItemName.text = currentPosition.itemName holder.itemView.txtItemPrice.text = "${currentPosition.itemPrice}" holder.itemView.txtItemQuantity.text = "${currentPosition.itemQuantity}" holder.itemView.ibDelete.setOnClickListener { viewModel.delete(currentPosition) } // To get total cost if (position == list.size - 1) { var totalCost = 0 for (i in 0 until list.size) { totalCost += list[i].itemPrice } holder.itemView.txtItemTotalCost.visibility = View.VISIBLE holder.itemView.txtTotalCostTitle.visibility = View.VISIBLE holder.itemView.txtItemTotalCost.text = "$totalCost" } } // Inner class for viewHolder inner class GroceryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) }
Paso 7: Para ingresar el artículo de comestibles, la cantidad y el precio del usuario, debemos crear una interfaz. Para implementar esta interfaz usaremos DialogBox. Primero cree la interfaz de usuario del cuadro de diálogo. En este cuadro de diálogo agregaremos tres editar texto y dos vistas de texto. Tres texto de edición para ingresar el nombre, la cantidad y el precio del artículo de comestibles. Dos vistas de texto, una para guardar y otra para cancelar. Después de hacer clic en Guardar texto, todos los datos se guardan en la base de datos y al hacer clic en el cuadro de diálogo Cancelar texto se cierra. Vaya a la aplicación > res > diseño . Haga clic con el botón derecho en el diseño , vaya a nuevo y luego agregue un archivo de recursos de diseño y asígnele el nombre de diálogo de comestibles . Consulte el código xml del archivo Groovedialog.xml .
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" android:layout_width="310dp" android:layout_height="250dp" android:background="@drawable/rectangle"> <!-- To display title--> <TextView android:id="@+id/tvTitle" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="15dp" android:layout_marginEnd="5dp" android:layout_marginRight="5dp" android:layout_marginBottom="26dp" android:text="@string/title" android:textColor="@color/black" android:textSize="30dp" app:layout_constraintBottom_toTopOf="@+id/linearLayout" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> <!-- Linear Layout is used to give equal weight sum to edit text--> <LinearLayout android:id="@+id/linearLayout" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginBottom="66dp" android:weightSum="3" app:layout_constraintBottom_toTopOf="@+id/tvSave" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/tvTitle"> <!-- Edit Text is used to Enter Grocery Item Name by user--> <EditText android:id="@+id/etItemName" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="0dp" android:layout_weight="1" android:hint="@string/etItem" android:textSize="30dp" app:layout_constraintBottom_toTopOf="@+id/tvCancel" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.069" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.661" /> <!-- Edit Text is used to Enter Grocery Item Quantity by user--> <EditText android:id="@+id/etItemQuantity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="0dp" android:layout_weight="1" android:hint="@string/etQuantity" android:inputType="number" android:textSize="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/etItemPrice" app:layout_constraintHorizontal_bias="0.461" app:layout_constraintStart_toEndOf="@+id/etItemName" app:layout_constraintTop_toBottomOf="@+id/tvTitle" app:layout_constraintVertical_bias="0.276" /> <!-- Edit Text is used to Enter Grocery Item Price by user--> <EditText android:id="@+id/etItemPrice" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="0dp" android:layout_weight="1" android:hint="@string/etPrice" android:inputType="number" android:textSize="30dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.861" app:layout_constraintStart_toEndOf="@+id/etItemName" app:layout_constraintTop_toTopOf="parent" /> </LinearLayout> <!-- Text view is used as save button to save all details in database by user--> <TextView android:id="@+id/tvSave" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="16dp" android:layout_marginRight="16dp" android:layout_marginBottom="14dp" android:text="@string/save" android:textColor="@color/black" android:textSize="20dp" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/tvCancel" app:layout_constraintTop_toBottomOf="@+id/linearLayout" /> <!-- Text View is used to close dialog box--> <TextView android:id="@+id/tvCancel" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="28dp" android:layout_marginLeft="28dp" android:layout_marginEnd="154dp" android:layout_marginRight="154dp" android:layout_marginBottom="14dp" android:text="@string/cancel" android:textColor="@color/black" android:textSize="20dp" android:textStyle="bold" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/tvSave" app:layout_constraintStart_toStartOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
Salida de código XML:
Para agregar un oyente de clics al guardar texto, primero debemos crear una interfaz en la que creamos una función. Vaya a la aplicación > java > com.example.application-name > UI. Haga clic con el botón derecho en el paquete de interfaz de usuario y cree un archivo/clase de Kotlin y cree un nombre de interfaz como DialogListener . Consulte el código del archivo DialogListener.kt .
Kotlin
package com.example.grocerylist.UI import com.example.grocerylist.Database.Entity.GroceryItems interface DialogListener { // Create a function to add items // in GroceryItems on clicking fun onAddButtonClicked(item:GroceryItems) }
Ahora crearemos una clase de diálogo de comestibles en la que guardaremos todas las entradas en diferentes variables y luego las insertaremos en la base de datos. Vaya a la aplicación > Java > com.example.application-name > UI. Haga clic con el botón derecho en el paquete de la interfaz de usuario y cree un archivo/clase de Kotlin y cree un nombre de clase GroceryItemDialog . Vea el siguiente código.
Kotlin
package com.example.grocerylist.UI import android.content.Context import android.os.Bundle import android.view.Window import android.widget.Toast import androidx.appcompat.app.AppCompatDialog import com.example.grocerylist.Database.Entity.GroceryItems import com.example.grocerylist.R import kotlinx.android.synthetic.main.grocerydialog.* class GroceryItemDialog(context: Context, var dialogListener: DialogListener) : AppCompatDialog(context) { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) supportRequestWindowFeature(Window.FEATURE_NO_TITLE) setContentView(R.layout.grocerydialog) // Click listener on Save button // to save all data. tvSave.setOnClickListener { // Take all three inputs in different variables from user // and add it in Grocery Items database val name = etItemName.text.toString() val quantity = etItemQuantity.text.toString().toInt() val price = etItemPrice.text.toString().toInt() // Toast to display enter items in edit text if (name.isEmpty()) { Toast.makeText(context, "Please Enter Item Name", Toast.LENGTH_SHORT).show() } val item = GroceryItems(name, quantity, price) dialogListener.onAddButtonClicked(item) dismiss() } // On click listener on cancel text to close dialog box tvCancel.setOnClickListener { cancel() } } }
Paso 8: En este paso finalmente codificaremos en nuestra MainActivity. En nuestra actividad principal, tenemos que configurar la vista del reciclador y agregar, haga clic en el oyente en el botón Agregar para abrir el cuadro de diálogo. 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.example.grocerylist.UI import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import androidx.lifecycle.ViewModelProvider import androidx.recyclerview.widget.LinearLayoutManager import com.example.grocerylist.Adapter.GroceryAdapter import com.example.grocerylist.Database.Entity.GroceryItems import com.example.grocerylist.Database.GroceryDatabase import com.example.grocerylist.Database.GroceryRepository import com.example.grocerylist.R import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { lateinit var ViewModel: GroceryViewModel lateinit var list: List<GroceryItems> override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val groceryRepository = GroceryRepository(GroceryDatabase(this)) val factory = GroceryViewModelFactory(groceryRepository) // Initialised View Model ViewModel = ViewModelProvider(this, factory).get(GroceryViewModel::class.java) val groceryAdapter = GroceryAdapter(listOf(), ViewModel) rvList.layoutManager = LinearLayoutManager(this) rvList.adapter = groceryAdapter // To display all items in recycler view ViewModel.allGroceryItems().observe(this, Observer { groceryAdapter.list = it groceryAdapter.notifyDataSetChanged() }) // on ClickListener on button to open dialog box btnAdd.setOnClickListener { GroceryItemDialog(this, object : DialogListener { override fun onAddButtonClicked(item: GroceryItems) { ViewModel.insert(item) } }).show() } } }
Así es como se ve la estructura completa del proyecto.
Producción:
Enlace Github: https://github.com/arpit-288/Fresh_Basket
Publicación traducida automáticamente
Artículo escrito por arpitsrivastava288 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA