Giới thiệu
Spinner mặc định của Android sử dụng layout hệ thống đơn giản. Để tùy chỉnh giao diện item (textSize, textColor, font, background...), cần tạo custom layout cho spinner item và dropdown item, sau đó gán vào ArrayAdapter.
Các bước thực hiện
Bước 1: Tạo dự án mới
Android Studio → File → New Project → Empty View Activity.
Bước 2: Tạo custom layout cho item hiển thị (res/layout/spinner_item.xml)
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="#2196F3"
android:textStyle="bold"
android:padding="16dp"
android:ellipsize="end"
android:maxLines="1" />
Bước 3: Tạo custom layout cho dropdown item (res/layout/spinner_dropdown_item.xml)
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="https://schemas.android.com/apk/res/android"
android:id="@android/id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:textColor="#333333"
android:padding="16dp"
android:background="?android:attr/selectableItemBackground" />
Bước 4: Thiết kế giao diện chính (res/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="24dp"
android:gravity="center"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Chọn siêu anh hùng:"
android:textSize="18sp"
android:layout_marginBottom="16dp" />
<Spinner
android:id="@+id/spinnerHeroes"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Bước 5: Code xử lý (MainActivity.java / MainActivity.kt)
Java:
package com.example.spinnercustom;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Spinner spinner = findViewById(R.id.spinnerHeroes);
String[] heroes = {"Batman", "Superman", "Flash", "Aquaman", "Shazam"};
// Adapter cho item hiển thị (closed state)
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this,
R.layout.spinner_item,
heroes
);
// Adapter cho dropdown list (open state)
adapter.setDropDownViewResource(R.layout.spinner_dropdown_item);
spinner.setAdapter(adapter);
}
}
Kotlin:
package com.example.spinnercustom
import android.os.Bundle
import android.widget.ArrayAdapter
import androidx.appcompat.app.AppCompatActivity
import com.example.spinnercustom.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val heroes = arrayOf("Batman", "Superman", "Flash", "Aquaman", "Shazam")
val adapter = ArrayAdapter(
this,
R.layout.spinner_item,
heroes
).apply {
setDropDownViewResource(R.layout.spinner_dropdown_item)
}
binding.spinnerHeroes.adapter = adapter
}
}
Nâng cao: Custom Adapter hoàn toàn (có icon, layout phức tạp)
Nếu cần hiển thị icon bên cạnh text, tạo custom adapter extends BaseAdapter hoặc dùng RecyclerView với Spinner replacement (Material Components ExposedDropdownMenu).
Ví dụ dùng Material ExposedDropdownMenu (khuyến nghị cho Material Design 3):
<!-- res/layout/activity_main.xml -->
<com.google.android.material.textfield.TextInputLayout
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Chọn siêu anh hùng">
<AutoCompleteTextView
android:id="@+id/autoCompleteHeroes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="none" />
</com.google.android.material.textfield.TextInputLayout>
// MainActivity.kt
val heroes = listOf("Batman", "Superman", "Flash", "Aquaman", "Shazam")
val adapter = ArrayAdapter(this, R.layout.dropdown_item, heroes)
binding.autoCompleteHeroes.setAdapter(adapter)
Lưu ý quan trọng
- ID của TextView trong custom layout phải là
@android:id/text1để ArrayAdapter tự tìm và set text. setDropDownViewResource()quyết định giao diện khi spinner mở rộng (dropdown).- Spinner cũ (
android.widget.Spinner) đã cũ, khuyến nghị dùng Material ExposedDropdownMenu (AutoCompleteTextView + TextInputLayout) cho UI hiện đại. - Để set textColor cho item được chọn (closed state), dùng layout
spinner_item.xml.