Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

Kotlin का उपयोग करके Android में RecyclerView को डेटाबेस (SQLite) के साथ कैसे उपयोग करें?

यह उदाहरण दर्शाता है कि Kotlin में SQLite डेटाबेस, RecyclerView, और कस्टम एडाप्टर का उपयोग करके संपर्क प्रबंधन ऐप कैसे बनाएं (CRUD ऑपरेशन के साथ)।

चरण 1 - नया प्रोजेक्ट बनाएं

Android Studio: File → New Project।

चरण 2 - build.gradle निर्भरताएं जोड़ें

dependencies {
    implementation "androidx.recyclerview:recyclerview:1.3.2"
    implementation "androidx.cardview:cardview:1.0.0"
    implementation "com.google.android.material:material:1.11.0"
}

चरण 3 - activity_main.xml लेआउट

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="4dp"
    tools:context=".MainActivity">
    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerViewContacts"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="60dp"
        android:paddingBottom="8dp" />
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/fabAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:contentDescription="संपर्क जोड़ें"
        android:src="@drawable/ic_baseline_add_24" />
</FrameLayout>

चरण 4 - डेटा मॉडल: Contact.kt

data class Contact(
    var id: Int = 0,
    var name: String = "",
    var phoneNumber: String = ""
)

चरण 5 - डेटाबेस हेल्पर: ContactDatabase.kt

import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper
import java.util.ArrayList

class ContactDatabase(context: Context) : SQLiteOpenHelper(
    context, "ContactsDB", null, 1
) {
    companion object {
        const val TABLE_CONTACTS = "contacts"
        const val COL_ID = "_id"
        const val COL_NAME = "name"
        const val COL_PHONE = "phone_number"
    }

    override fun onCreate(db: SQLiteDatabase) {
        val createTable = "CREATE TABLE $TABLE_CONTACTS (" +
            "$COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
            "$COL_NAME TEXT, " +
            "$COL_PHONE TEXT)"
        db.execSQL(createTable)
    }

    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
        db.execSQL("DROP TABLE IF EXISTS $TABLE_CONTACTS")
        onCreate(db)
    }

    fun addContact(contact: Contact): Long {
        val db = writableDatabase
        val values = ContentValues().apply {
            put(COL_NAME, contact.name)
            put(COL_PHONE, contact.phoneNumber)
        }
        return db.insert(TABLE_CONTACTS, null, values)
    }

    fun getAllContacts(): ArrayList {
        val contacts = ArrayList()
        val db = readableDatabase
        val cursor = db.rawQuery("SELECT * FROM $TABLE_CONTACTS ORDER BY $COL_NAME", null)
        
        if (cursor.moveToFirst()) {
            do {
                contacts.add(Contact(
                    id = cursor.getInt(cursor.getColumnIndexOrThrow(COL_ID)),
                    name = cursor.getString(cursor.getColumnIndexOrThrow(COL_NAME)),
                    phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow(COL_PHONE))
                ))
            } while (cursor.moveToNext())
        }
        cursor.close()
        return contacts
    }

    fun updateContact(contact: Contact): Int {
        val db = writableDatabase
        val values = ContentValues().apply {
            put(COL_NAME, contact.name)
            put(COL_PHONE, contact.phoneNumber)
        }
        return db.update(TABLE_CONTACTS, values, "$COL_ID = ?", arrayOf(contact.id.toString()))
    }

    fun deleteContact(id: Int): Int {
        val db = writableDatabase
        return db.delete(TABLE_CONTACTS, "$COL_ID = ?", arrayOf(id.toString()))
    }
}

चरण 6 - व्यू होल्डर: ContactViewHolder.kt

import android.view.View
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

class ContactViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    val tvName: TextView = itemView.findViewById(R.id.tvContactName)
    val tvPhone: TextView = itemView.findViewById(R.id.tvPhoneNumber)
    val ivEdit: ImageView = itemView.findViewById(R.id.ivEdit)
    val ivDelete: ImageView = itemView.findViewById(R.id.ivDelete)
}

चरण 7 - एडाप्टर: ContactAdapter.kt

import android.app.Activity
import android.content.Context
import android.text.TextUtils
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.EditText
import android.widget.Filter
import android.widget.Filterable
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.RecyclerView
import java.util.ArrayList

class ContactAdapter(
    private val context: Context,
    private var contacts: ArrayList
) : RecyclerView.Adapter(), Filterable {

    private val originalContacts = ArrayList()
    private val db = ContactDatabase(context)

    init {
        originalContacts.addAll(contacts)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContactViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_contact, parent, false)
        return ContactViewHolder(view)
    }

    override fun onBindViewHolder(holder: ContactViewHolder, position: Int) {
        val contact = contacts[position]
        holder.tvName.text = contact.name
        holder.tvPhone.text = contact.phoneNumber

        holder.ivEdit.setOnClickListener { showEditDialog(contact) }
        holder.ivDelete.setOnClickListener { 
            db.deleteContact(contact.id)
            refreshData()
        }
    }

    override fun getItemCount() = contacts.size

    private fun showEditDialog(contact: Contact) {
        val view = LayoutInflater.from(context).inflate(R.layout.dialog_add_edit_contact, null)
        val etName = view.findViewById(R.id.etName)
        val etPhone = view.findViewById(R.id.etPhone)
        etName.setText(contact.name)
        etPhone.setText(contact.phoneNumber)

        AlertDialog.Builder(context)
            .setTitle("संपर्क संपादित करें")
            .setView(view)
            .setPositiveButton("सहेजें") { _, _ ->
                val name = etName.text.toString().trim()
                val phone = etPhone.text.toString().trim()
                if (TextUtils.isEmpty(name)) {
                    Toast.makeText(context, "नाम दर्ज करें", Toast.LENGTH_SHORT).show()
                    return@setPositiveButton
                }
                contact.name = name
                contact.phoneNumber = phone
                db.updateContact(contact)
                refreshData()
            }
            .setNegativeButton("रद्द करें", null)
            .show()
    }

    private fun refreshData() {
        contacts.clear()
        contacts.addAll(db.getAllContacts())
        notifyDataSetChanged()
    }

    override fun getFilter(): Filter = object : Filter() {
        override fun performFiltering(constraint: CharSequence?): FilterResults {
            val query = constraint?.toString()?.lowercase() ?: ""
            val filtered = if (query.isEmpty()) {
                originalContacts
            } else {
                originalContacts.filter { it.name.lowercase().contains(query) }.toCollection(ArrayList())
            }
            return FilterResults().apply { values = filtered; count = filtered.size }
        }

        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            @Suppress("UNCHECKED_CAST")
            val filtered = results?.values as? ArrayList ?: ArrayList()
            contacts.clear()
            contacts.addAll(filtered)
            notifyDataSetChanged()
        }
    }
}

चरण 8 - लेआउट फाइलें

item_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginHorizontal="8dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:padding="16dp">
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:orientation="vertical">
            <TextView
                android:id="@+id/tvContactName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="16sp"
                android:textStyle="bold" />
            <TextView
                android:id="@+id/tvPhoneNumber"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="14sp"
                android:textColor="#666" />
        </LinearLayout>
        <ImageView
            android:id="@+id/ivEdit"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="8dp"
            android:contentDescription="संपादित करें"
            android:src="@drawable/ic_baseline_edit_24" />
        <ImageView
            android:id="@+id/ivDelete"
            android:layout_width="24dp"
            android:layout_height="24dp"
            android:layout_gravity="center_vertical"
            android:layout_marginStart="8dp"
            android:contentDescription="हटाएं"
            android:src="@drawable/ic_baseline_delete_24" />
    </LinearLayout>
</androidx.cardview.widget.CardView>

dialog_add_edit_contact.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp">
    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="नाम"
        android:inputType="textPersonName"
        android:maxLines="1" />
    <EditText
        android:id="@+id/etPhone"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="12dp"
        android:hint="फोन नंबर"
        android:inputType="phone"
        android:maxLines="1" />
</LinearLayout>

चरण 9 - MainActivity.kt पूर्ण

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.floatingactionbutton.FloatingActionButton

class MainActivity : AppCompatActivity() {
    private lateinit var recyclerView: RecyclerView
    private lateinit var fabAdd: FloatingActionButton
    private lateinit var etSearch: EditText
    private val db = ContactDatabase(this)
    private lateinit var adapter: ContactAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "संपर्क प्रबंधक"

        recyclerView = findViewById(R.id.recyclerViewContacts)
        fabAdd = findViewById(R.id.fabAdd)
        
        // खोज फील्ड एक्शन बार में या लेआउट में जोड़ें
        // यहां सरलता के लिए FAB क्लिक पर डायलॉग दिखाते हैं

        recyclerView.layoutManager = LinearLayoutManager(this)
        recyclerView.setHasFixedSize(true)

        loadContacts()

        fabAdd.setOnClickListener { showAddDialog() }
    }

    private fun loadContacts() {
        val contacts = db.getAllContacts()
        adapter = ContactAdapter(this, contacts)
        recyclerView.adapter = adapter
    }

    private fun showAddDialog() {
        val view = layoutInflater.inflate(R.layout.dialog_add_edit_contact, null)
        val etName = view.findViewById(R.id.etName)
        val etPhone = view.findViewById(R.id.etPhone)

        AlertDialog.Builder(this)
            .setTitle("नया संपर्क जोड़ें")
            .setView(view)
            .setPositiveButton("जोड़ें") { _, _ ->
                val name = etName.text.toString().trim()
                val phone = etPhone.text.toString().trim()
                if (name.isNotEmpty()) {
                    db.addContact(Contact(name = name, phoneNumber = phone))
                    loadContacts()
                }
            }
            .setNegativeButton("रद्द करें", null)
            .show()
    }

    override fun onDestroy() {
        super.onDestroy()
        // db.close() // SQLiteOpenHelper स्वतः प्रबंधित करता है
    }
}

चरण 10 - AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.contactmanager">
    <application ...>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

ऐप चलाएं

ऐप चलाएं। FAB (+) दबाकर नए संपर्क जोड़ें। सूची में संपर्क दिखेंगे। खोज के लिए टूलबार में SearchView जोड़ें। संपादित/हटाएं आइकन पर टैप करके संपर्क प्रबंधित करें।

आधुनिक सर्वोत्तम अभ्यास:
  • Room Database: SQLiteOpenHelper के बजाय Room (ORM) का उपयोग करें - कम बॉयलरप्लेट, कंपाइल-टाइम SQL जांच, LiveData/Flow समर्थन
  • ViewBinding: findViewById के बजाय ViewBinding उपयोग करें
  • DiffUtil + ListAdapter: RecyclerView एडाप्टर में notifyDataSetChanged() के बजाय DiffUtil का उपयोग करें
  • Coroutines/Flow: डेटाबेस ऑपरेशन IO थ्रेड पर करें
  1. ConstraintLayout के साथ RecyclerView का उपयोग कैसे करें? ConstraintLayout के साथ RecyclerView का उपयोग कैसे करें?

    RecyclerView आइटम लेआउट के रूप में ConstraintLayout ConstraintLayout एक फ्लैट व्यू पदानुक्रम (नेस्टिंग के बिना) की अनुमति देता है, जो RecyclerView आइटम के लिए प्रदर्शन में सुधार करता है। यह गाइड एक कार्ड-शैली ग्रिड आइटम के लिए एक प्रतिक्रियाशील, बाधा-आधारित आइटम लेआउट दिखाता है। निर्भरताएं dependen

  1. Android में डेटाबेस के साथ RecyclerView का उपयोग कैसे करें? Android में डेटाबेस के साथ RecyclerView का उपयोग कैसे करें?

    Android में SQLite डेटाबेस के साथ RecyclerView इम्प्लीमेंटेशन यह ट्यूटोरियल दिखाता है कि कैसे Room Database (आधुनिक) या SQLiteOpenHelper (लीगेसी) के साथ RecyclerView को जोड़ा जाता है, CRUD ऑपरेशन्स (बनाएं, पढ़ें, अपडेट करें, हटाएं) के साथ। आधुनिक दृष्टिकोण: Room Database (अनुशंसित) चरण 1: निर्भरता

  1. Android ऐप में SQLite डेटाबेस का उपयोग कैसे करें? Android ऐप में SQLite डेटाबेस का उपयोग कैसे करें?

    परिचय यह विस्तृत ट्यूटोरियल दर्शाता है कि Android ऐप में SQLite डेटाबेस का उपयोग करके डेटा कैसे स्टोर, पढ़ें, अपडेट और डिलीट करें। हम एक पूर्ण CRUD (Create, Read, Update, Delete) उदाहरण बनाएंगे जिसमें फुटबॉल खिलाड़ियों का डेटा मैनेज किया जाएगा। आवश्यक चरण चरण 1: नया प्रोजेक्ट बनाएं Android Studio