MASIGNCLEAN102

Membuat Aplikasi Android Kotlin CRUD Toko Komputer dengan SQLite

 Membuat Aplikasi Android Kotlin CRUD  Toko Komputer dengan SQLite - Assalamualaikum, pada artikel kali ini kita akan belajar bagaimana cara membuat aplikasi android crud dengan sqlite menggunakan bahasa pemrograman kotlin. Setelah mungkin di artikel lama saya yang berjudul Membuat Aplikasi CRUD Android dengan MySQL Database, kita menggunakan bahasa pemrograman java dan menggunakan REST API PHP.


Aplikasi Toko Komputer dengan SQLite kali ini kita akan menggunakan material design dari google. Material design merupakan sebuah librari yang menjadi standar design dari google yang belakangan ini sedang trend penggunaannya untuk aplikasi modern / kekinian.


SQLite merupakan sebuah librari database lokal. Letak file penyimpanan data dari SQLite berada di direktori lokai dari perangkat terinstall. Maka dari itu, penggunaan SQLite sebatas untuk data lokal yang tidak perlu diakses dari internet. Nah pada artikel kali ini kita akan menggunakan itu.



Mari langsung ke pembahasannya.


Membuat Aplikasi Android Kotlin CRUD Toko Komputer dengan SQLite


Dalam pembuatan aplikasi ini akan terdapat beberapa tahap mulai dari tahap instalasi projek sampai ke tahap pengujian.

Di aplikasi ini akan terdapat 2 activity, yaitu MainActivity untuk penambahan data dan GudangActivity untuk menampilkan data yang ada


Buat Projek Baru

Buatlah sebuah projek baru, pilih Empty Activity kemudian beri nama projek terserah kalian.




Buat Activity Gudang


Buatlah sebuah activity baru, beri nama GudangActivity. Klik kanan pada nama package -> new -> activity. Pilih yang empty activity.


Membuat Layout


Pertama kita bisa memulai dengan membuat layout dari activity yang ada.

MainActivity Layout


<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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"
    tools:context=".MainActivity"
    android:background="@color/cream">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        >
        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/tb_main"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/prm"
            app:titleTextColor="@color/white"
            app:title="Alfan Comp Store"
            app:logo="@drawable/ic_baseline_computer_24"
            app:titleCentered="false"
            app:titleMarginStart="20dp"
            >
        </com.google.android.material.appbar.MaterialToolbar>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_margin="16dp"
            >
            <com.google.android.material.textview.MaterialTextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Input Data Laptop"
                app:fontFamily="@font/poppins"
                android:textSize="25sp"
                android:textAlignment="center"
                android:textColor="@color/prm"
                android:textStyle="bold"
                app:autoSizeTextType="uniform"
                />
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical"
                android:paddingTop="30dp"
                >
                <com.google.android.material.textfield.TextInputLayout
                    android:id="@+id/textBrand"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Merek Laptop"
                    app:errorEnabled="true"
                    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"

                    >
                    <AutoCompleteTextView
                        android:id="@+id/tv_brand"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="none"
                        />
                </com.google.android.material.textfield.TextInputLayout>

                <com.google.android.material.textfield.TextInputLayout
                    android:id="@+id/textSeri"
                    android:layout_marginTop="20dp"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="Seri Laptop"
                    app:errorEnabled="true"
                    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                    >
                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/tv_seri"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="text"
                        />

                </com.google.android.material.textfield.TextInputLayout>

                <com.google.android.material.textfield.TextInputLayout
                    android:id="@+id/textHarga"
                    style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:hint="Harga"
                    app:prefixText="Rp">

                    <com.google.android.material.textfield.TextInputEditText
                        android:id="@+id/tv_harga"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:inputType="number"
                        />
                    
                </com.google.android.material.textfield.TextInputLayout>

                <com.google.android.material.textview.MaterialTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:textAlignment="center"
                    android:textColor="@color/prm"
                    android:fontFamily="@font/poppins"
                    android:textStyle="bold"
                    android:text="Status Jual"
                    />
                <RadioGroup
                    android:id="@+id/rg_status"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:checkedButton="@id/rb_available"
                    android:orientation="horizontal"
                    android:gravity="center"
                    >

                    <com.google.android.material.radiobutton.MaterialRadioButton
                        android:id="@+id/rb_available"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Available"
                        />
                    <com.google.android.material.radiobutton.MaterialRadioButton
                        android:id="@+id/rb_po"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Pre-Order"
                        />
                </RadioGroup>

                <com.google.android.material.textview.MaterialTextView
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="20dp"
                    android:textAlignment="center"
                    android:textColor="@color/prm"
                    android:fontFamily="@font/poppins"
                    android:textStyle="bold"
                    android:text="Tag"
                    />

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    android:gravity="center_horizontal"
                    >
                    <com.google.android.material.chip.ChipGroup
                        android:id="@+id/cg_tag"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        app:selectionRequired="true"
                        >
                        <com.google.android.material.chip.Chip
                            android:id="@+id/c_ram4"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            style="@style/Widget.MaterialComponents.Chip.Choice"
                            android:text="Ram 4GB"
                            />
                        <com.google.android.material.chip.Chip
                            android:id="@+id/c_ram2"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            style="@style/Widget.MaterialComponents.Chip.Choice"
                            android:text="Ram 2GB"
                            />
                        <com.google.android.material.chip.Chip
                            android:id="@+id/c_intel"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            style="@style/Widget.MaterialComponents.Chip.Choice"
                            android:text="Intel"
                            />
                        <com.google.android.material.chip.Chip
                            android:id="@+id/c_amd"
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            style="@style/Widget.MaterialComponents.Chip.Choice"
                            android:text="AMD"
                            />
                    </com.google.android.material.chip.ChipGroup>

                </LinearLayout>

                <RelativeLayout
                    android:id="@+id/btn_submit"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:background="@drawable/button_1"
                    android:paddingVertical="15dp"
                    android:layout_marginTop="30dp"
                    android:gravity="center_horizontal"
                    >
                    <TextView
                        android:id="@+id/tv_submit"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Submit"
                        android:textColor="@color/white"
                        android:fontFamily="@font/poppins"
                        />
                    <ImageView
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/ic_baseline_arrow_right_alt_24"
                        android:layout_toRightOf="@id/tv_submit"
                        android:layout_marginLeft="10dp"
                        />
                </RelativeLayout>
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>
</androidx.core.widget.NestedScrollView>



 

Layout Item Recycler View

Selanjutnya kita bisa memulai dengan membuat layout item untuk recyclerview kita. Layout ini nantinya akan menjadi layout yang ditampilkan di gudang activity untuk menampilkan daftar laptop / komputer yang ada di database SQLite kita.

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="150dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_margin="16dp"
    app:cardCornerRadius="15dp"
    app:cardElevation="10dp"
    app:rippleColor="@color/cream"
    android:id="@+id/cv_item">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:layout_margin="15dp"
        android:weightSum="2"
        >
        <com.google.android.material.imageview.ShapeableImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="0.3"
            android:src="@drawable/laptop"
            />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1.2"
            android:orientation="vertical"
            android:layout_margin="15dp"
            >
            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/tv_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Asus GX-150 Nvidia"
                android:fontFamily="@font/poppins"
                android:textStyle="bold"
                android:textColor="@color/prm"
                android:textSize="15sp"
                />
            <com.google.android.material.textview.MaterialTextView
                android:id="@+id/tv_harga"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Rp 10.000.000"
                android:fontFamily="@font/poppins"
                android:textColor="@color/stone"
                android:layout_marginTop="5dp"
                />
            <com.google.android.material.chip.ChipGroup
                android:id="@+id/cg_tags"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="5dp"
                >
            </com.google.android.material.chip.ChipGroup>
        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="0.5"
            android:layout_height="match_parent"
            android:gravity="center"
            >
            <LinearLayout
                android:id="@+id/ll_status"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal"
                android:background="@drawable/button_2"
                >
                <com.google.android.material.textview.MaterialTextView
                    android:id="@+id/tv_status"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="Available"
                    android:fontFamily="@font/poppins"
                    android:textSize="12sp"
                    android:textColor="@color/white"
                    android:paddingVertical="3dp"
                    android:paddingHorizontal="5dp"
                    android:textAlignment="center"
                    />

            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</com.google.android.material.card.MaterialCardView>

 




Gudang Activity Layout

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

    <com.google.android.material.appbar.MaterialToolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/prm"
        app:titleTextColor="@color/white"
        app:title="Alfan Comp Store"
        app:logo="@drawable/ic_baseline_computer_24"
        app:titleCentered="false"
        app:titleMarginStart="20dp"
        >

    </com.google.android.material.appbar.MaterialToolbar>


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_gudang"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        tools:listitem="@layout/gudang_items">

    </androidx.recyclerview.widget.RecyclerView>

</LinearLayout>


Membuat Data Class Model

Data Class Model merupakan sebuah data class yang berfungsi sebagai model dari data yang ada di database kita. Sama seperti getter dan setter pada java, tetapi di kotlin lebih simple dan clean.

Buatlah sebuah class baru beri nama, LaptopModel.kt 

Isi dengan kode berikut :

data class LaptopModel(val id: Int? , val brand: String?, val seri: String?, val harga: Int?, val status: String?, val tags: String?) {
}

 

Membuat Class SQLiteHelper

SQLite helper / DB helper merupakan sebuah class yang nantinya kita gunakan untuk segala urusan / transaksi data dengan sqlite.

Sesuaikan variabel di kode bawah ini dengan kondisi aplikasi mu,

val DATABASENAME = "tokokompalfan"
val TABLENAME = "laptop"
val COL_ID  = "id"
val COL_BRAND = "brand"
val COL_SERI = "seri"
val COL_HARGA = "harga"
val COL_STATUS = "status"
val COL_TAGS = "tags"


class DBHelper(val context: Context): SQLiteOpenHelper(context, DATABASENAME,null,1) {
    override fun onCreate(p0: SQLiteDatabase?) {
        val createTable = "CREATE TABLE " + TABLENAME + " (" + COL_ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + COL_BRAND + " VARCHAR(20)," + COL_SERI + " VARCHAR(30), " +
                COL_HARGA + " INTEGER, " + COL_STATUS + " VARCHAR(20), " + COL_TAGS + " VARCHAR(50) )"
        p0?.execSQL(createTable)
    }

    override fun onUpgrade(p0: SQLiteDatabase?, p1: Int, p2: Int) {
        TODO("Not yet implemented")
    }

    fun insertData(laptop: LaptopModel) {
        val database = this.writableDatabase
        val contentValues = ContentValues()
        contentValues.put(COL_BRAND, laptop.brand)
        contentValues.put(COL_SERI, laptop.seri)
        contentValues.put(COL_HARGA, laptop.harga)
        contentValues.put(COL_STATUS, laptop.status)
        contentValues.put(COL_TAGS, laptop.tags)
        val result = database.insert(TABLENAME, null, contentValues)
        if (result == (0).toLong()) {
            Toast.makeText(context, "Failed", Toast.LENGTH_SHORT).show()
        }
        else {
            Toast.makeText(context, "Success", Toast.LENGTH_SHORT).show()
        }
    }

    @SuppressLint("Range")
    fun readData(): ArrayList<LaptopModel> {
        val list: ArrayList<LaptopModel> = ArrayList()
        val db = this.readableDatabase
        val query = "Select * from $TABLENAME"
        val result = db.rawQuery(query, null)
        if (result.moveToFirst()) {
            do {
                val id = result.getString(result.getColumnIndex(COL_ID)).toInt()
                val brand = result.getString(result.getColumnIndex(COL_BRAND))
                val seri = result.getString(result.getColumnIndex(COL_SERI))
                val harga = result.getString(result.getColumnIndex(COL_HARGA)).toInt()
                val status = result.getString(result.getColumnIndex(COL_STATUS))
                val tags = result.getString(result.getColumnIndex(COL_TAGS))
                val laptop = LaptopModel(id,brand,seri,harga,status,tags)
                list.add(laptop)
            }
            while (result.moveToNext())
        }
        return list
    }

    fun deleteData(id: Int?){
        val db = this.readableDatabase
        db.execSQL("delete from ${TABLENAME} where ${COL_ID} = '"+id+"'")
    }

}


Bisa diliat di kode atas tadi, ada fungsi read data, insertData dan deleteData. Fungsi nantinya yang akan kita panggil ketika proses CRUD di aplikasi.


Membuat RecyclerView Adapter


RecyclerView Adapter merupakan sebuah class yang berfungsi untuk menjembatani data dengan view / layout.

Buat sebuah class baru beri nama GudangAdapter.

class GudangAdapter(private var laptopList: ArrayList<LaptopModel>,private val context: Context):

    RecyclerView.Adapter<GudangAdapter.MyViewHolder>() {

    class MyViewHolder(view: View): RecyclerView.ViewHolder(view){

        val binding     = GudangItemsBinding.bind(view)

        val cv_item     = binding.cvItem

        val tv_title    = binding.tvTitle

        val tv_harga    = binding.tvHarga

        val cg_tags     = binding.cgTags

        val ll_status   = binding.llStatus

        val tv_status   = binding.tvStatus


    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): GudangAdapter.MyViewHolder {

        val itemView = LayoutInflater.from(parent.context).

                inflate(R.layout.gudang_items,parent,false)

        return MyViewHolder(itemView)

    }


    override fun onBindViewHolder(holder: GudangAdapter.MyViewHolder, position: Int) {

        holder.tv_title.text    = laptopList.get(position).brand + " " + laptopList.get(position).seri

        holder.tv_harga.text    = "Rp. ${laptopList.get(position).harga.toString()}"

        holder.tv_status.text   = laptopList.get(position).status


        var status = laptopList.get(position).status

        if(status == "Available"){

           holder.ll_status.setBackgroundResource(R.drawable.button_2)

        }else{

           holder.ll_status.setBackgroundResource(R.drawable.button_3)

        }


        val arrTags             = laptopList.get(position).tags?.split(",")?.toTypedArray()

        if (arrTags != null) {

            for (tags in arrTags){

                val chip: Chip = Chip(context)

                chip.text = tags

                chip.ensureAccessibleTouchTarget(50)

                holder.cg_tags.addView(chip)

            }

        }


        holder.cv_item.setOnLongClickListener {

            val mBuilder = AlertDialog.Builder(context)


            mBuilder.setMessage("Ingin Menghapus Data?")

                .setCancelable(false)

                .setPositiveButton("Ya",DialogInterface.OnClickListener{

                    dialogInterface, i ->

                    val dbHelper = DBHelper(context)

                    dbHelper.deleteData(laptopList.get(position).id)


                    laptopList.removeAt(position)

                    notifyDataSetChanged()



                    mBuilder.show().dismiss()

                })

                .setNegativeButton("Tidak", DialogInterface.OnClickListener { dialogInterface, i ->

                    dialogInterface.cancel()

                })


            mBuilder.setOnDismissListener {

                notifyDataSetChanged()

            }


            mBuilder.setTitle("Hapus Data")

            mBuilder.show()


            return@setOnLongClickListener true

        }


    }


    override fun getItemCount(): Int {

        return laptopList.size

    }



}


Activity Kotlin


Setelah tadi kita membangun fondasi aplikasi nya, mari kita lanjut di bagian activity nya.

MainActivity

class MainActivity : AppCompatActivity() {
    private lateinit var binding: ActivityMainBinding
    private val tagList = ArrayList<String>()
    private val TAG: String = "Main"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //Database
        val db = DBHelper(applicationContext)

        //Text Input Layout
        val textBrand   = binding.textBrand
        val textHarga   = binding.textHarga
        val textSeri    = binding.textSeri

        val items = listOf("Asus", "Acer", "Lenovo", "Dell", "Zyrex")
        val adapter = ArrayAdapter(applicationContext, R.layout.list_brand, items)
        (textBrand.editText as? AutoCompleteTextView)?.setAdapter(adapter)

        //TextView
        val tv_brand    = binding.tvBrand
        val tv_seri     = binding.tvSeri
        val tv_harga    = binding.tvHarga

        //Radio
        val rg_status       = binding.rgStatus
        val rb_available    = binding.rbAvailable
        val rb_po           = binding.rbPo

        //Chip
        val cg_tag      = binding.cgTag

        //Button
        val btn_submit  = binding.btnSubmit

        btn_submit.setOnClickListener {
            val brand   = tv_brand.text.toString()
            val seri    = tv_seri.text.toString()
            val price   = tv_harga.text.toString()

            if (brand.isEmpty()){
                textBrand.error = "Missing Brand Value"
                return@setOnClickListener
            }
            if(seri.isEmpty()){
                textSeri.error = "Missing Seri Value"
                return@setOnClickListener
            }
            if(price == null){
                textHarga.error = "Missing Harga Value"
                return@setOnClickListener
            }


            val harga   = Integer.parseInt(tv_harga.text.toString())

            binding.tvBrand.setText("")
            binding.tvSeri.setText("")
            binding.tvHarga.setText("")
            tagList.clear()

            val id_status   = rg_status.checkedRadioButtonId
            val status      = findViewById<RadioButton>(id_status).text.toString()
            val chips       = cg_tag.checkedChipIds

            var string_tags = ""
            for(chip in chips){
                tagList.add(findViewById<Chip>(chip).text.toString())
                string_tags += findViewById<Chip>(chip).text.toString() + ","
            }
            string_tags = string_tags.toString().dropLast(1)
            db.insertData(LaptopModel(null,brand,seri,harga,status,string_tags))

            val intent = Intent(this,GudangActivity::class.java)
            startActivity(intent)

        }

        setupMenu()
    }

    fun setupMenu(){
        val tb_main = binding.tbMain
        tb_main.inflateMenu(R.menu.menu_1)

        tb_main.setOnMenuItemClickListener {
            when(it.itemId){
                R.id.menu_pindah -> {
                    val intent = Intent(this,GudangActivity::class.java)
                    startActivity(intent)
                }
            }

            return@setOnMenuItemClickListener false
        }
    }

}

 

GudangActivity

class GudangActivity : AppCompatActivity() {
    private lateinit var binding: ActivityGudangBinding
    private val laptopList = ArrayList<LaptopModel>()
    private val TAG = "Gudang"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityGudangBinding.inflate(layoutInflater)
        setContentView(binding.root)

        //Database
        val db  = DBHelper(this)

        for(laptops in db.readData()){
         laptopList.add(laptops)
        }
        val rv_gudang = binding.rvGudang

        val gudangAdapter = GudangAdapter(laptopList, this)
        val layoutManager = LinearLayoutManager(this)
        with(rv_gudang) {
            setLayoutManager(layoutManager)
            adapter = gudangAdapter
            itemAnimator = DefaultItemAnimator()
            setHasFixedSize(true)
        }
        gudangAdapter.notifyDataSetChanged()
    }
}


Yak, selesai bisa dicoba build dan diperiksa pasti ada error hehe.

Test




Selesai, semoga artikel Membuat Aplikasi Android Kotlin CRUD Toko Komputer dengan SQLite kali ini bisa membantu kalian untuk belajar android lebih giat lagi ya. Tetap pantengin funtechsy ya supaya bisa dapat tutorial seputar pemrograman terbaru.

Terima kasih sudah membaca. Wassalamualaikum :)



Share This :
Funtechsy

avatar

assalamualaikum,"menu_pindah" itu darimana ?

3 April 2023 pukul 21.01