ListView với nhiều kiểu dữ liệu
ArrayAdapter<String> chỉ hiển thị text đơn giản. Để hiển thị nhiều kiểu dữ liệu (String, Integer, Object tùy chỉnh), cần Custom Adapter hoặc dùng toString().
Cách 1: Dùng toString() của Object (Đơn giản)
// Model class
public class Item {
String name;
int age;
double score;
boolean active;
public Item(String name, int age, double score, boolean active) {
this.name = name; this.age = age; this.score = score; this.active = active;
}
@Override
public String toString() {
return name + " | Tuổi: " + age + " | Điểm: " + score + " | " + (active ? "Active" : "Inactive");
}
}
// Trong Activity
ArrayList<Item> items = new ArrayList<>();
items.add(new Item("An", 20, 8.5, true));
items.add(new Item("Bình", 22, 9.0, false));
ArrayAdapter<Item> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, items);
listView.setAdapter(adapter); // Tự gọi toString()
Cách 2: Custom ArrayAdapter (Khuyên dùng cho UI phức tạp)
public class ItemAdapter extends ArrayAdapter<Item> {
public ItemAdapter(Context context, List<Item> items) {
super(context, 0, items);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Item item = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.item_layout, parent, false);
}
TextView tvName = convertView.findViewById(R.id.tvName);
TextView tvAge = convertView.findViewById(R.id.tvAge);
TextView tvScore = convertView.findViewById(R.id.tvScore);
ImageView ivStatus = convertView.findViewById(R.id.ivStatus);
tvName.setText(item.name);
tvAge.setText("Tuổi: " + item.age);
tvScore.setText("Điểm: " + item.score);
ivStatus.setImageResource(item.active ? R.drawable.ic_active : R.drawable.ic_inactive);
return convertView;
}
}
Cách 3: Collections.checkedCollection (Kiểm tra kiểu tại runtime)
ArrayList<String> list = new ArrayList<>();
// Chỉ cho phép thêm String, ném ClassCastException nếu kiểu khác
Collection<String> safeList = Collections.checkedCollection(list, String.class);
safeList.add("OK"); // OK
safeList.add(123); // Compile error (generic) hoặc Runtime ClassCastException
Ví dụ demo (tương tự bài trước)
findViewById(R.id.save).setOnClickListener(v -> {
String input = edtName.getText().toString().trim();
if (input.isEmpty()) { edtName.setError("Nhập giá trị"); return; }
nameSet.add(input);
edtName.setText("");
dataList.clear();
dataList.addAll(nameSet);
// Kiểm tra kiểu dữ liệu (demo)
Collections.checkedCollection(dataList, String.class);
adapter.notifyDataSetChanged();
Toast.makeText(this, "Đã thêm: " + input, Toast.LENGTH_SHORT).show();
});
Kết quả

ListView hiển thị cả chuỗi và số (đã chuyển thành String).
So sánh các cách
| Cách | Độ phức tạp | Tùy chỉnh UI | Hiệu năng |
|---|---|---|---|
| toString() + ArrayAdapter | Thấp | Không (1 dòng text) | Tốt |
| Custom ArrayAdapter | Trung bình | Hoàn toàn (layout tùy ý) | Tốt (ViewHolder) |
| RecyclerView + Adapter | Cao | Hoàn toàn + animation | Tốt nhất |
Khuyến nghị
- Dữ liệu đơn giản, chỉ text: ArrayAdapter + toString().
- Cần hiển thị ảnh, nhiều trường, click từng item: Custom Adapter hoặc RecyclerView.
- Luôn định nghĩa model class rõ ràng thay vì dùng Object/List<Object>.