ngodingdulu

Spinner (Combo Box) di Android: Data Statis & dari JSON

Oleh Afa HernandesDiperbarui 6 menit baca

Seri · Bagian 3 dari 9Komponen UI Android
  1. 1Cara Membuat Project Baru di Android Studio
  2. 2Membuat Loading/Splash Screen di Android Studio
  3. 3Spinner (Combo Box) di Android: Data Statis & dari JSON
  4. 4Cara Menggunakan RadioButton di Android
  5. 5Cara Membuat Alert Dialog di Android Studio (Lengkap + Loading)
  6. 6Date Picker Dialog di Android
  7. 7Cara Load Gambar dari URL di Android
  8. 8Membuka URL & Aplikasi Lain dari Button Android (Uri.parse)
  9. 9Source Code Halaman Dashboard UI Android
Daftar isi

Spinner adalah komponen drop-down di Android, yang di dunia web biasa disebut combo box atau <select>. Spinner cocok untuk pilihan yang jumlahnya terbatas, seperti agama, jenis kelamin, jurusan, atau kategori produk. Layar tetap ringkas, dan pengguna tidak perlu mengetik.

Di tutorial ini kita membuat dua spinner:

  1. Spinner dengan data statis dari string-array, misalnya daftar agama
  2. Spinner dengan data dari server dalam format JSON, misalnya daftar beasiswa dari database MySQL

Kita juga membahas cara mengambil nilai yang dipilih dan cara memilih item secara otomatis berdasarkan nilai tertentu. Ini sangat dibutuhkan untuk form edit data.

Persiapan

  • Android Studio versi terbaru, project Empty Views Activity dengan bahasa Java
  • Untuk bagian JSON: web server lokal seperti XAMPP dengan PHP dan MySQL

Langkah 1: Buat layout

Buka res/layout/activity_main.xml:

res/layout/activity_main.xml
<?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="match_parent"
android:orientation="vertical"
android:padding="24dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Agama" />
<Spinner
android:id="@+id/spinAgama"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="Beasiswa" />
<Spinner
android:id="@+id/spinBeasiswa"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="48dp" />
<TextView
android:id="@+id/tvHasil"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:textStyle="bold" />
</LinearLayout>

Langkah 2: Spinner dengan data statis

Untuk data tetap, simpan pilihan di file resource, bukan di dalam kode Java. Buat file res/values/arrays.xml:

res/values/arrays.xml
<resources>
<string-array name="agama">
<item>Islam</item>
<item>Kristen</item>
<item>Katolik</item>
<item>Hindu</item>
<item>Buddha</item>
<item>Konghucu</item>
</string-array>
</resources>

Lalu hubungkan ke Spinner lewat ArrayAdapter di onCreate():

MainActivity.java
Spinner spinAgama = findViewById(R.id.spinAgama);
ArrayAdapter<CharSequence> adapterAgama = ArrayAdapter.createFromResource(
this, R.array.agama, android.R.layout.simple_spinner_item);
adapterAgama.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinAgama.setAdapter(adapterAgama);

Ada dua layout bawaan Android yang dipakai di sini: simple_spinner_item untuk tampilan saat Spinner tertutup, dan simple_spinner_dropdown_item untuk daftar saat Spinner dibuka.

Alternatif: jika datanya berasal dari array Java, gunakan new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, arrayAnda). Cara pakai selanjutnya sama.

Langkah 3: Ambil nilai yang dipilih

Pasang OnItemSelectedListener untuk merespons setiap kali pengguna memilih item:

MainActivity.java
spinAgama.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String dipilih = parent.getItemAtPosition(position).toString();
tvHasil.setText("Agama: " + dipilih);
}
@Override
public void onNothingSelected(AdapterView<?> parent) { }
});

Jika nilainya hanya dibutuhkan saat tombol Simpan ditekan, Anda tidak perlu listener. Cukup baca spinAgama.getSelectedItem().toString() saat menyimpan.

Langkah 4: Pilih item otomatis berdasarkan nilai

Di form edit data, Spinner harus langsung menampilkan nilai yang tersimpan, misalnya “Hindu”. Gunakan getPosition() dari adapter:

MainActivity.java
String agamaTersimpan = "Hindu"; // misalnya dari database atau JSON
int posisi = adapterAgama.getPosition(agamaTersimpan);
if (posisi >= 0) {
spinAgama.setSelection(posisi);
}

getPosition() membedakan huruf besar dan kecil. Kalau data dari database bisa berbeda kapitalisasinya, samakan dulu formatnya, misalnya dengan menyimpan nilai persis seperti di arrays.xml.

Langkah 5: Spinner dengan data JSON dari server

Untuk data yang bisa berubah, seperti daftar beasiswa, ambil datanya dari server. Kita butuh tiga bagian: endpoint PHP yang mengirim JSON, class model, dan kode Android yang mengambil data di background thread.

Endpoint PHP

Contoh tabel beasiswa dengan kolom id_beasiswa dan nama_beasiswa. Simpan file berikut di htdocs/api/beasiswa_show.php:

htdocs/api/beasiswa_show.php
<?php
header('Content-Type: application/json');
$conn = new mysqli('localhost', 'root', '', 'db_kampus');
if ($conn->connect_error) {
echo json_encode(['sukses' => 0, 'pesan' => 'Koneksi database gagal']);
exit;
}
$result = $conn->query('SELECT id_beasiswa, nama_beasiswa FROM beasiswa ORDER BY nama_beasiswa');
echo json_encode([
'sukses' => 1,
'record' => $result->fetch_all(MYSQLI_ASSOC),
]);

Buka alamatnya di browser untuk memastikan hasilnya seperti ini:

Contoh respons
{
"sukses": 1,
"record": [
{ "id_beasiswa": "B01", "nama_beasiswa": "Beasiswa Prestasi" },
{ "id_beasiswa": "B02", "nama_beasiswa": "KIP Kuliah" }
]
}

Class model

Spinner sering perlu menampilkan nama tetapi menyimpan ID. Daripada memakai dua array terpisah, buat class kecil. Teks yang tampil di Spinner diambil dari toString():

Beasiswa.java
public class Beasiswa {
public final String id;
public final String nama;
public Beasiswa(String id, String nama) {
this.id = id;
this.nama = nama;
}
@Override
public String toString() {
return nama; // teks yang tampil di Spinner
}
}

Mengambil data di background

Request jaringan tidak boleh dijalankan di thread utama. Versi lama tutorial ini memakai AsyncTask, yang sudah deprecated sejak Android 11. Penggantinya adalah ExecutorService untuk proses di background dan Handler untuk kembali ke thread utama. Keduanya sudah tersedia tanpa library tambahan.

MainActivity.java
// ganti dengan IP komputer Anda; dari emulator, localhost komputer = 10.0.2.2
private static final String BASE_URL = "http://10.0.2.2/api/";
private final ExecutorService executor = Executors.newSingleThreadExecutor();
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private void muatBeasiswa() {
executor.execute(() -> {
List<Beasiswa> hasil = new ArrayList<>();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) new URL(BASE_URL + "beasiswa_show.php").openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) sb.append(line);
}
JSONObject json = new JSONObject(sb.toString());
if (json.getInt("sukses") == 1) {
JSONArray record = json.getJSONArray("record");
for (int i = 0; i < record.length(); i++) {
JSONObject o = record.getJSONObject(i);
hasil.add(new Beasiswa(o.getString("id_beasiswa"), o.getString("nama_beasiswa")));
}
}
} catch (Exception e) {
Log.e("Spinner", "Gagal memuat beasiswa", e);
} finally {
if (conn != null) conn.disconnect();
}
// kembali ke thread utama untuk mengubah tampilan
mainHandler.post(() -> tampilkanBeasiswa(hasil));
});
}
private void tampilkanBeasiswa(List<Beasiswa> data) {
ArrayAdapter<Beasiswa> adapter = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, data);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinBeasiswa.setAdapter(adapter);
}
@Override
protected void onDestroy() {
super.onDestroy();
executor.shutdown();
}

Panggil muatBeasiswa() di onCreate(). Untuk mengambil ID dari item yang dipilih:

MainActivity.java
Beasiswa terpilih = (Beasiswa) spinBeasiswa.getSelectedItem();
String idBeasiswa = terpilih.id; // simpan ID ini ke database, bukan namanya

Izin internet

Tambahkan izin berikut di AndroidManifest.xml, di luar tag <application>:

AndroidManifest.xml
<uses-permission android:name="android.permission.INTERNET" />

Karena contoh ini memakai http:// (bukan https://), Android 9 ke atas akan memblokir request-nya secara default. Ikuti langkah di artikel Mengatasi JSON/HTTP Tidak Jalan di Android 9+ untuk mengizinkannya saat pengembangan.

Error yang sering muncul

NetworkOnMainThreadException. Request jaringan dijalankan langsung di onCreate(). Pindahkan ke background thread seperti contoh executor.execute() di atas.

Spinner kosong padahal JSON muncul di browser. Periksa tiga hal: izin INTERNET sudah ada, alamat server benar (gunakan 10.0.2.2 di emulator, atau IP komputer Anda di HP sungguhan), dan request http:// sudah diizinkan. Lihat pesan error lengkapnya di tab Logcat dengan filter Spinner.

onItemSelected terpanggil sendiri saat aplikasi dibuka. Itu perilaku normal: Spinner selalu memilih item pertama saat adapter dipasang. Jika ini mengganggu, abaikan panggilan pertama dengan sebuah variabel penanda, atau baca nilainya hanya saat tombol Simpan ditekan.

ClassCastException saat getSelectedItem(). Tipe adapter tidak sesuai dengan yang di-cast. Spinner beasiswa memakai ArrayAdapter<Beasiswa>, jadi cast ke Beasiswa, bukan ke String.

Pertanyaan yang sering diajukan

Apakah ada pengganti Spinner yang lebih modern? Untuk tampilan Material Design, banyak aplikasi memakai Exposed Dropdown Menu, yaitu AutoCompleteTextView di dalam TextInputLayout dari library Material Components. Tampilannya mirip kolom input dengan panah. Konsep adapter-nya sama dengan Spinner.

Bagaimana jika datanya ratusan item? Spinner kurang nyaman untuk daftar panjang karena pengguna harus menggulir. Gunakan AutoCompleteTextView agar pengguna bisa mengetik untuk mencari.

Kesimpulan

Spinner diisi lewat ArrayAdapter: gunakan createFromResource() untuk data statis, dan list objek model untuk data dari server. Ambil nilai dengan getSelectedItem(), pilih nilai tersimpan dengan getPosition() + setSelection(), dan pastikan request jaringan berjalan di background thread.

Lanjutkan ke bagian berikutnya di seri Komponen UI Android: RadioButton.

Bagikan:WhatsAppTelegramXFacebook
MobileSource Code

Source Code Halaman Dashboard UI Android

Pada tutorial bahasa pemrograman kali ini, saya akan membagikan sebuah tutorial tentang bagaimana caranya membuat Halaman Menu Utama yang

4 Februari 20216 mnt

Enter bukaEsc tutupHalaman pencarian