Cara Membuat Fitur Upload Foto dengan Kotlin

Dalam artikel ini, kita akan membuat fitur upload foto menggunakan Kotlin untuk aplikasi Android. Fitur ini memungkinkan pengguna untuk memilih gambar dari galeri perangkat mereka dan mengunggahnya ke aplikasi.

Snapshoot Fitur Upload

1. Layout UI

Kita akan menggunakan tiga file layout XML untuk menyiapkan tampilan aplikasi kita:

a. mahasiswa.xml

Layout ini akan menampilkan daftar mahasiswa dan menyediakan tombol untuk menambahkan mahasiswa baru.

<!-- Tampilan daftar mahasiswa dan tombol tambah -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    tools:context=".Mahasiswa"
    android:padding="10dp">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:weightSum="12"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginBottom="10dp">
        <TextView
            android:id="@+id/txt_nama_user"
            android:layout_width="wrap_content"
            android:layout_weight="9"
            android:layout_height="wrap_content"
            android:text="Nama Pelogin"></TextView>
        <Button
            android:id="@+id/btn_logout"
            android:layout_width="wrap_content"
            android:layout_weight="3"
            android:layout_height="wrap_content"
            android:text="Logout"></Button>
    </LinearLayout>

    <Button
        android:id="@+id/btn_tambah"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Tambah Mahasiswa"
        android:layout_margin="10dp"></Button>

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_mahasiswa"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:listitem="@layout/mahasiswa_item"></androidx.recyclerview.widget.RecyclerView>


</LinearLayout>

b. mahasiswa_item.xml

Layout ini digunakan untuk menampilkan detail mahasiswa, termasuk foto dan tombol untuk menghapus atau mengubah data mahasiswa.

<!-- Tampilan detail mahasiswa -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:gravity="center"
    android:layout_margin="5dp">

    <ImageView
        android:id="@+id/iv_foto"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:src="@drawable/noimage"
        android:scaleType="centerCrop"></ImageView>

    <TextView
        android:id="@+id/txt_nim"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="NIM Mahasiswa"
        android:textSize="18sp"
        android:textColor="#333333"
        android:layout_marginBottom="5dp"></TextView>

    <TextView
        android:id="@+id/txt_nama"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Nama Mahasiswa"
        android:textSize="16sp"
        android:textColor="#333333"
        android:layout_marginBottom="5dp"></TextView>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:layout_marginTop="5dp"
        android:gravity="center">
        <Button
            android:id="@+id/btn_hapus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hapus"
            android:layout_marginRight="5dp"></Button>
        <Button
            android:id="@+id/btn_ubah"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="5dp"
            android:text="Ubah"></Button>
    </LinearLayout>

</LinearLayout>

c. mahasiswa_tambah.xml

Layout ini memungkinkan pengguna untuk menambahkan mahasiswa baru dengan memasukkan NIM, nama, dan memilih foto.

<!-- Form untuk menambahkan mahasiswa baru -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp"
    tools:context=".Mahasiswa_Tambah">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Tambah Mahasiswa"
        android:textSize="20sp"
        android:layout_marginBottom="20dp"
        android:layout_gravity="center_horizontal"></TextView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:text="NIM Mahasiswa"></TextView>
    <EditText
        android:id="@+id/edt_nim"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:hint="Masukkan NIM"></EditText>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:text="Nama Mahasiswa"></TextView>
    <EditText
        android:id="@+id/edt_nama"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        android:hint="Masukkan Nama"></EditText>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="5dp"
        android:text="Pilih Foto"></TextView>
    <ImageView
        android:id="@+id/iv_upload"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:src="@drawable/noimage"
        android:layout_marginBottom="30dp"></ImageView>
    <Button
        android:id="@+id/btn_simpan"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="SIMPAN"></Button>

</LinearLayout>

2. Logika Kotlin

Kita akan menggunakan tiga file Kotlin untuk mengimplementasikan logika aplikasi kita:

a. Mahasiswa.kt

File ini merupakan Activity utama yang menampilkan daftar mahasiswa dan menyediakan fitur untuk menambah, mengubah, atau menghapus data mahasiswa.

// Logika untuk menampilkan daftar mahasiswa dan mengelola data
package com.android.kampus

import android.content.Intent
import android.content.SharedPreferences
import android.database.sqlite.SQLiteDatabase
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import java.io.ByteArrayInputStream

class Mahasiswa : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.mahasiswa)
        
        // Inisialisasi tampilan dari layout XML
        val rv_mahasiswa:RecyclerView = findViewById(R.id.rv_mahasiswa)
        val txt_nama_user:TextView = findViewById(R.id.txt_nama_user)

        // Dapatkan nama user yang login dari session
        val tiket:SharedPreferences = getSharedPreferences("user", MODE_PRIVATE)
        val nama_user:String = tiket.getString("nama_user", null).toString()
        txt_nama_user.text = nama_user

        // Inisialisasi list untuk data mahasiswa
        val id_mahasiswa:MutableList<String> = mutableListOf()
        val nama:MutableList<String> = mutableListOf()
        val nim:MutableList<String> = mutableListOf()
        val foto:MutableList<Bitmap> = mutableListOf()

        // Panggil database kampus
        val dbkampus:SQLiteDatabase = openOrCreateDatabase("kampus", MODE_PRIVATE, null)

        // Ambil data mahasiswa dari database
        val gali_mahasiswa = dbkampus.rawQuery("SELECT * FROM mahasiswa", null)

        while (gali_mahasiswa.moveToNext())
        {
            try {
                // Konversi blob gambar menjadi Bitmap
                val bis = ByteArrayInputStream(gali_mahasiswa.getBlob(3))
                val gambarbitmap:Bitmap = BitmapFactory.decodeStream(bis)
                foto.add(gambarbitmap)
            } catch (e:Exception) {
                // Jika gagal membaca gambar, tampilkan gambar default
                val gambarbitmap:Bitmap = BitmapFactory.decodeResource(this.resources,R.drawable.noimage)
                foto.add(gambarbitmap)
            }

            // Ambil data id, nama, dan NIM mahasiswa
            id_mahasiswa.add(gali_mahasiswa.getString(0))
            nama.add(gali_mahasiswa.getString(1))
            nim.add(gali_mahasiswa.getString(2))
        }

        // Inisialisasi adapter untuk RecyclerView
        val mi = Mahasiswa_Item(this,   id_mahasiswa, nama, nim, foto)

        // Set adapter dan layout manager untuk RecyclerView
        rv_mahasiswa.adapter = mi
        rv_mahasiswa.layoutManager = GridLayoutManager (this, 2)

        // Mengatur aksi ketika tombol tambah ditekan
        val btn_tambah:Button = findViewById(R.id.btn_tambah)
        btn_tambah.setOnClickListener {
            val pindah:Intent = Intent(this, Mahasiswa_Tambah::class.java)
            startActivity(pindah)
        }

        // Mengatur aksi ketika tombol logout ditekan
        val btn_logout:Button = findViewById(R.id.btn_logout)
        btn_logout.setOnClickListener {
            // Menghapus session/tiket user
            val edittiket = tiket.edit()
            edittiket.clear()
            edittiket.commit()

            // Pindah halaman ke halaman login dan tutup activity saat ini
            val pindah:Intent = Intent(this, Login::class.java)
            startActivity(pindah)
            finish()
        }
    }
}

b. Mahasiswa_Item.kt

File ini merupakan adapter untuk RecyclerView pada mahasiswa.xml. Adapter ini bertanggung jawab untuk menampilkan data mahasiswa dalam daftar.

// Adapter untuk RecyclerView yang menampilkan daftar mahasiswa
package com.android.kampus

import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

// Kelas Mahasiswa_Item mewarisi RecyclerView.Adapter dan menggunakan ViewHolder generic
class Mahasiswa_Item (val ini:Context, val id_mahasiswa:MutableList<String>, val nama:MutableList<String>, val nim:MutableList<String>, val foto:MutableList<Bitmap>) : RecyclerView.Adapter<Mahasiswa_Item.ViewHolder>(){
    
    // Mendefinisikan ViewHolder untuk setiap item dalam RecyclerView
    class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView){
        val txt_nama:TextView = ItemView.findViewById(R.id.txt_nama) // Menemukan TextView untuk nama mahasiswa
        val txt_nim:TextView = ItemView.findViewById(R.id.txt_nim) // Menemukan TextView untuk NIM mahasiswa
        val iv_foto:ImageView = ItemView.findViewById(R.id.iv_foto) // Menemukan ImageView untuk foto mahasiswa
        val btn_hapus:Button = ItemView.findViewById(R.id.btn_hapus) // Menemukan Button untuk menghapus data mahasiswa
        val btn_ubah:Button = ItemView.findViewById(R.id.btn_ubah) // Menemukan Button untuk mengubah data mahasiswa
    }
    
    // Menentukan tata letak untuk setiap item dalam RecyclerView
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Mahasiswa_Item.ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.mahasiswa_item, parent, false)
        return ViewHolder(view)
    }
    
    // Mendapatkan jumlah item dalam daftar
    override fun getItemCount(): Int {
        return nama.size
    }

    // Mengikat data ke tampilan dalam ViewHolder
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.txt_nama.text = nama.get(position) // Menetapkan nama mahasiswa
        holder.txt_nim.text = nim.get(position) // Menetapkan NIM mahasiswa
        holder.iv_foto.setImageBitmap(foto.get(position)) // Menetapkan foto mahasiswa
        
        // Menambahkan aksi ketika tombol hapus ditekan
        holder.btn_hapus.setOnClickListener {
            // Mendapatkan id_mahasiswa sesuai posisi tombol yang ditekan
            val id_mahasiswa_terpilih:String = id_mahasiswa.get(position)
            
            // Pindah ke activity Mahasiswa_Hapus dengan membawa id_mahasiswa_terpilih sebagai data ekstra
            val pindah:Intent = Intent(ini, Mahasiswa_Hapus::class.java)
            pindah.putExtra("id_mahasiswa_terpilih", id_mahasiswa_terpilih)
            ini.startActivity(pindah)
        }
        
        // Menambahkan aksi ketika tombol ubah ditekan
        holder.btn_ubah.setOnClickListener {
            // Mendapatkan id_mahasiswa sesuai posisi tombol yang ditekan
            val id_mahasiswa_terpilih:String = id_mahasiswa.get(position)
            
            // Pindah ke activity Mahasiswa_Ubah dengan membawa id_mahasiswa_terpilih sebagai data ekstra
            val pindah:Intent = Intent(ini, Mahasiswa_Ubah::class.java)
            pindah.putExtra("id_mahasiswa_terpilih", id_mahasiswa_terpilih)
            ini.startActivity(pindah)
        }
    }
}

c. Mahasiswa_Tambah.kt

File ini digunakan untuk menambahkan mahasiswa baru. Pengguna dapat memasukkan NIM, nama, dan memilih foto mahasiswa.

// Logika untuk menambahkan mahasiswa baru dan mengunggah foto
package com.android.kampus

import android.app.Activity
import android.content.Intent
import android.database.sqlite.SQLiteDatabase
import android.graphics.Bitmap
import android.net.Uri
import android.os.Bundle
import android.provider.MediaStore
import android.util.Log
import android.widget.Button
import android.widget.EditText
import android.widget.ImageView
import androidx.activity.enableEdgeToEdge
import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import java.io.ByteArrayOutputStream

class Mahasiswa_Tambah : AppCompatActivity() {
    // Variabel untuk menyimpan URI gambar dari galeri
    var urlgambar: Uri? = null
    
    // Variabel untuk menyimpan bitmap gambar yang dipilih dari galeri
    var bitmapgambar: Bitmap? = null
    
    // ImageView untuk menampilkan gambar yang dipilih
    var iv_upload: ImageView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.mahasiswa_tambah)
        
        // Inisialisasi komponen tampilan
        val edt_nim: EditText = findViewById(R.id.edt_nim)
        val edt_nama: EditText = findViewById(R.id.edt_nama)
        val btn_simpan: Button = findViewById(R.id.btn_simpan)
        iv_upload = findViewById(R.id.iv_upload)

        // Menambahkan aksi ketika ImageView untuk mengunggah gambar diklik
        iv_upload?.setOnClickListener {
            // Membuka galeri untuk memilih gambar
            val bukagaleri: Intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.INTERNAL_CONTENT_URI)
            pilih_gambar.launch(bukagaleri)
        }

        // Menambahkan aksi ketika tombol simpan ditekan
        btn_simpan.setOnClickListener {
            // Mendapatkan teks dari EditText untuk NIM dan nama
            val isi_nim: String = edt_nim.text.toString()
            val isi_nama: String = edt_nama.text.toString()

            // Mengonversi gambar yang dipilih menjadi ByteArray
            val bos = ByteArrayOutputStream()
            bitmapgambar?.compress(Bitmap.CompressFormat.JPEG, 100, bos)
            val bytearraygambar = bos.toByteArray()

            // Membuka atau membuat database SQLite dengan nama "kampus"
            val dbkampus: SQLiteDatabase = openOrCreateDatabase("kampus", MODE_PRIVATE, null)

            // Query untuk menyimpan data mahasiswa ke database
            val sql = "INSERT INTO mahasiswa (nim_mahasiswa, nama_mahasiswa, foto_mahasiswa) VALUES (?,?,?)"
            val statement = dbkampus.compileStatement(sql)
            statement.clearBindings()
            statement.bindString(1, isi_nim)
            statement.bindString(2, isi_nama)
            statement.bindBlob(3, bytearraygambar)
            statement.executeInsert()

            // Kembali ke activity Mahasiswa setelah menyimpan data
            val pindah: Intent = Intent(this, Mahasiswa::class.java)
            startActivity(pindah)
        }
    }
    
    // Register untuk menerima hasil pemilihan gambar dari galeri
    val pilih_gambar = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
        if (it.resultCode == Activity.RESULT_OK) {
            val gambardiperoleh = it.data

            if (gambardiperoleh != null) {
                // Mendapatkan URI gambar yang dipilih
                urlgambar = gambardiperoleh.data

                // Mengonversi URI gambar ke bitmap
                bitmapgambar = MediaStore.Images.Media.getBitmap(contentResolver, urlgambar)
                
                // Menampilkan gambar yang dipilih ke ImageView
                iv_upload?.setImageBitmap(bitmapgambar)
            }
        }
    }
}

Dengan demikian, kita telah membuat fitur upload foto menggunakan Kotlin untuk aplikasi Android. Fitur ini memungkinkan pengguna untuk memilih gambar dari galeri dan mengunggahnya ke aplikasi. Semoga artikel ini bermanfaat bagi Anda dalam pengembangan aplikasi Android Anda!