Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีอัปเดต ListView หลังเพิ่มข้อมูลใน SQLite Android ด้วย Kotlin

ตัวอย่างนี้สาธิตวิธี เพิ่มข้อมูลลง SQLite Database แล้ว Refresh ListView ให้แสดงข้อมูลล่าสุดโดยใช้ notifyDataSetChanged()

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → New Project → Empty Activity

ขั้นตอนที่ 2: Layout (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/etName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Name" />

    <EditText
        android:id="@+id/etSalary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="Enter Salary"
        android:inputType="numberDecimal" />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="8dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnSave"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Save" />

        <Button
            android:id="@+id/btnRefresh"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="8dp"
            android:text="Refresh" />
    </LinearLayout>

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:layout_marginTop="16dp" />

</LinearLayout>

ขั้นตอนที่ 3: Database Helper (DatabaseHelper.kt)

import android.content.ContentValues
import android.content.Context
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteOpenHelper

class DatabaseHelper(context: Context) : SQLiteOpenHelper(
    context, "salary_database", null, 1
) {
    companion object {
        const val TABLE_NAME = "salary_details"
        const val COL_ID = "id"
        const val COL_NAME = "name"
        const val COL_SALARY = "salary"
    }

    override fun onCreate(db: SQLiteDatabase) {
        db.execSQL("CREATE TABLE $TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_NAME TEXT, $COL_SALARY TEXT)")
    }

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

    fun addData(name: String, salary: String): Boolean {
        val db = writableDatabase
        val values = ContentValues().apply {
            put(COL_NAME, name)
            put(COL_SALARY, salary)
        }
        return db.insert(TABLE_NAME, null, values) != -1L
    }

    fun getAllContacts(): List {
        val db = readableDatabase
        val list = mutableListOf()
        val cursor = db.rawQuery("SELECT $COL_NAME FROM $TABLE_NAME", null)
        cursor.use {
            while (it.moveToNext()) {
                list.add(it.getString(it.getColumnIndexOrThrow(COL_NAME)))
            }
        }
        return list
    }
}

ขั้นตอนที่ 4: โค้ดหลัก (MainActivity.kt)

import android.os.Bundle
import android.widget.*
import androidx.appcompat.app.AppCompatActivity

class MainActivity : AppCompatActivity() {
    private lateinit var etName: EditText
    private lateinit var etSalary: EditText
    private lateinit var btnSave: Button
    private lateinit var btnRefresh: Button
    private lateinit var listView: ListView
    private lateinit var adapter: ArrayAdapter
    private val nameList = mutableListOf()
    private val dbHelper = DatabaseHelper(this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "SQLite ListView Demo"

        etName = findViewById(R.id.etName)
        etSalary = findViewById(R.id.etSalary)
        btnSave = findViewById(R.id.btnSave)
        btnRefresh = findViewById(R.id.btnRefresh)
        listView = findViewById(R.id.listView)

        // โหลดข้อมูลเริ่มต้น
        loadData()

        // Adapter
        adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, nameList)
        listView.adapter = adapter

        // Save Button
        btnSave.setOnClickListener {
            val name = etName.text.toString().trim()
            val salary = etSalary.text.toString().trim()

            if (name.isEmpty() || salary.isEmpty()) {
                etName.error = if (name.isEmpty()) "Enter Name" else null
                etSalary.error = if (salary.isEmpty()) "Enter Salary" else null
                return@setOnClickListener
            }

            if (dbHelper.addData(name, salary)) {
                Toast.makeText(this, "Inserted", Toast.LENGTH_SHORT).show()
                etName.text.clear()
                etSalary.text.clear()
                loadData() // โหลดใหม่
            } else {
                Toast.makeText(this, "Insert Failed", Toast.LENGTH_SHORT).show()
            }
        }

        // Refresh Button
        btnRefresh.setOnClickListener {
            loadData()
            Toast.makeText(this, "Refreshed", Toast.LENGTH_SHORT).show()
        }
    }

    private fun loadData() {
        nameList.clear()
        nameList.addAll(dbHelper.getAllContacts())
        adapter.notifyDataSetChanged() // 🔑 จุดสำคัญ: บอก Adapter ว่าข้อมูลเปลี่ยน
    }
}

ขั้นตอนที่ 5: AndroidManifest.xml

Manifest มาตรฐาน

🔑 จุดสำคัญ: การ Refresh ListView

  1. แก้ไขข้อมูลใน List ที่ผูกกับ Adapter (clear/addAll)
  2. เรียก adapter.notifyDataSetChanged() เพื่อบอก ListView ให้วาดใหม่
  3. ไม่ต้อง setAdapter ใหม่

💡 แนวทางทันสมัย (Recommended)

ปัจจุบันแนะนำให้ใช้ RecyclerView + Room Database + LiveData/Flow ซึ่ง:

  • อัปเดต UI อัตโนมัติเมื่อข้อมูลเปลี่ยน (Observer Pattern)
  • ประสิทธิภาพดีกว่า ListView
  • รองรับ Animation, DiffUtil

ทดสอบ

  1. กรอก Name + Salary → กด Save
  2. ListView จะแสดงชื่อที่เพิ่งเพิ่มทันที
  3. กด Refresh เพื่อโหลดใหม่จาก DB