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
Buat Projek Baru
Buat Activity Gudang
Membuat Layout
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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.google.android.material.appbar.MaterialToolbarandroid: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><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:layout_margin="16dp"><com.google.android.material.textview.MaterialTextViewandroid: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"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:paddingTop="30dp"><com.google.android.material.textfield.TextInputLayoutandroid: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"><AutoCompleteTextViewandroid: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.TextInputLayoutandroid: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.TextInputEditTextandroid: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.TextInputLayoutandroid: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.TextInputEditTextandroid: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.MaterialTextViewandroid: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"/><RadioGroupandroid: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.MaterialRadioButtonandroid:id="@+id/rb_available"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Available"/><com.google.android.material.radiobutton.MaterialRadioButtonandroid:id="@+id/rb_po"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Pre-Order"/></RadioGroup><com.google.android.material.textview.MaterialTextViewandroid: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"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:gravity="center_horizontal"><com.google.android.material.chip.ChipGroupandroid:id="@+id/cg_tag"android:layout_width="wrap_content"android:layout_height="wrap_content"app:selectionRequired="true"><com.google.android.material.chip.Chipandroid: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.Chipandroid: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.Chipandroid: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.Chipandroid: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><RelativeLayoutandroid: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"><TextViewandroid: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"/><ImageViewandroid: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
<?xml version="1.0" encoding="utf-8"?><com.google.android.material.card.MaterialCardViewxmlns: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"><LinearLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="horizontal"android:layout_margin="15dp"android:weightSum="2"><com.google.android.material.imageview.ShapeableImageViewandroid:layout_width="0dp"android:layout_height="match_parent"android:layout_weight="0.3"android:src="@drawable/laptop"/><LinearLayoutandroid: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.MaterialTextViewandroid: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.MaterialTextViewandroid: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.ChipGroupandroid: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><LinearLayoutandroid:layout_width="0dp"android:layout_weight="0.5"android:layout_height="match_parent"android:gravity="center"><LinearLayoutandroid: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.MaterialTextViewandroid: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"?><LinearLayoutxmlns: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.MaterialToolbarandroid: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.RecyclerViewandroid: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 LaptopModel(val id: Int? , val brand: String?, val seri: String?, val harga: Int?, val status: String?, val tags: String?) {
}
Membuat Class SQLiteHelper
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.writableDatabaseval 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.readableDatabaseval 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.readableDatabasedb.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
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
MainActivity
class MainActivity : AppCompatActivity() {private lateinit var binding: ActivityMainBindingprivate val tagList = ArrayList<String>()private val TAG: String = "Main"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityMainBinding.inflate(layoutInflater)setContentView(binding.root)//Databaseval db = DBHelper(applicationContext)//Text Input Layoutval textBrand = binding.textBrandval textHarga = binding.textHargaval textSeri = binding.textSerival items = listOf("Asus", "Acer", "Lenovo", "Dell", "Zyrex")val adapter = ArrayAdapter(applicationContext, R.layout.list_brand, items)(textBrand.editText as? AutoCompleteTextView)?.setAdapter(adapter)//TextViewval tv_brand = binding.tvBrandval tv_seri = binding.tvSerival tv_harga = binding.tvHarga//Radioval rg_status = binding.rgStatusval rb_available = binding.rbAvailableval rb_po = binding.rbPo//Chipval cg_tag = binding.cgTag//Buttonval btn_submit = binding.btnSubmitbtn_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.checkedRadioButtonIdval status = findViewById<RadioButton>(id_status).text.toString()val chips = cg_tag.checkedChipIdsvar 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.tbMaintb_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: ActivityGudangBindingprivate val laptopList = ArrayList<LaptopModel>()private val TAG = "Gudang"override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)binding = ActivityGudangBinding.inflate(layoutInflater)setContentView(binding.root)//Databaseval db = DBHelper(this)for(laptops in db.readData()){laptopList.add(laptops)}val rv_gudang = binding.rvGudangval gudangAdapter = GudangAdapter(laptopList, this)val layoutManager = LinearLayoutManager(this)with(rv_gudang) {setLayoutManager(layoutManager)adapter = gudangAdapteritemAnimator = DefaultItemAnimator()setHasFixedSize(true)}gudangAdapter.notifyDataSetChanged()}}
Yak, selesai bisa dicoba build dan diperiksa pasti ada error hehe.
comment 1 komentar
more_vertassalamualaikum,"menu_pindah" itu darimana ?
3 April 2023 pukul 21.01