Lập trình Android – Adapter

Adapter là gì?

Một Adapter là một đối tượng của một lớp cài đặt giao diện Adapter. Nó đóng vai trò như là một liên kết giữa một tập hợp dữ liệu và một Adapter View, một đối tượng của một lớp thừa kế lớp trừu tượng AdapterView. Tập hợp dữ liệu có thể là bất cứ điều gì mà trình bày dữ liệu một cách có cấu trúc. Mảng, các đối tượng List và các đối tượng Cursor thường sử dụng bộ dữ liệu.

Một Adapter có trách nhiệm lấy dữ liệu từ bộ dữ liệu và tạo ra các đối tượng View dựa trên dữ liệu đó. Các đối tượng View được tạo ra sau đó được sử dụng để gắn lên bất kỳ Adapter View mà ràng buộc với Adapter

Bạn có thể tạo các lớp Adapter riêng của bạn từ đầu, nhưng hầu hết các nhà phát triển muốn sử dụng hoặc thừa kế các lớp Adapter được cung cấp bởi Android SDK, chẳng hạn như ArrayAdapter và SimpleCursorAdapter. Trong hướng dẫn này, chúng ta sẽ tập trung vào lớp ArrayAdapter.

Dưới đây sơ đồ Apdapter

Adapter View làm việc như thế nào?

Adapter View có thể hiển thị các bộ dữ liệu lớn rất hiệu quả. Ví dụ, ListView và GridView có thể hiển thị hàng triệu phần tử mà không có bất cứ độ trễ đáng kể nào trong khi vẫn sử dụng bộ nhớ và CPU rất thấp. Chúng có thể làm điều đó như thế nào? Các Adapter View khác nhau tuân theo những chiến lược khác nhau. Tuy nhiên, đây là những gì mà hầu hết chúng thường làm.

  • Chúng chỉ kết xuất những đối tượng View mà đã trên màn hình hoặc nó đang di chuyển vào màn hình. Bằng cách này, bộ nhớ tiêu thụ bởi một Adapter View có thể được cố định và độc lập với kích thước của tập dữ liệu.

  • Chúng cũng cho phép các nhà phát triển giảm thiểu công sức cho các hoạt động inflate layout và tái sử dụng các đối tượng View sẵn có đã di chuyển khỏi màn. Điều này sẽ giúp tiêu thụ CPU thấp.

 

Apdapter trong Android

Trong Android, Adapter thường được sử dụng để liên kết dữ liệu với UI

  1. BaseAdapter – Là lớp adpater cơ sở cho các Adapter khác 

  2. ArrayAdapter –Một ListAdapter có thể quản lí một ListView chứa danh sách các phần tử có kiểu bất kì

  3. Custom ArrayAdapter – Thường được sử dụng để hiển thị một danh sách tùy chỉnh

  4. SimpleAdapter – Nó là một Adapter đơn giản và dễ hiểu để ánh xạ dữ liệu vào những View được định nghĩa trong một tập tin XML

  5. Custom SimpleAdapter – Nó được sử dụng để hiển thị một danh sách được tùy chỉnh để truy cập các mục con của List hoặc Grid.

Chúng ta sẽ xem chi tiết từng Adapter 
1. BaseAdapter
 Là lớp adpater cơ sở cho các Adapter thường dùng khác như ArrayAdapter<T>, CursorAdapter, SimpleAdapter. BaseAdapter thường đóng vai trò Adapter cho các ListView và Spinner sẽ được tìm hiểu trong các phần tiếp theo. 

public class CustomAdapter extends BaseAdapter {

@Override
public int getCount() {
return 0;
}

@Override
public Object getItem(int i) {
return null;
}

@Override
public long getItemId(int i) {
return 0;
}

@Override
public View getView(int i, View view, ViewGroup viewGroup) {

return null;
}

Chú ý: có thể dùng lớp ListAdapter hoặc lớp SpinnerAdapter làm Adapter lần lượt  cho ListView và Spinner. Nhưng 2 lớp này chỉ là lớp ảo xây dựng trên lớp BaseAdapter mà thôi.   

Ví dụ trên chúng ta override lại các phương thức của BaseAdapter được sử dụng để thiết lập lại dữ liệu trong ListView, GirdView, Spinner.
2.  ArrayAdapter
Một ListAdapter có thể quản lí một ListView chứa danh sách các phần tử có kiểu bất kì. Việc rất đơn giản, bạn chỉ cần “móc nối” dữ liệu với TextView thông qua ID của nó với mỗi dòng trong ListView là một TextView – ví dụ như ListView gồm danh sách tên sinh viên mà thôi. Nếu bạn muốn mỗi dòng ListView phức tạp hơn tức là gồm nhiều thành phần hơn thì nên dùng một mảng để giữ tất cả các ID của các TextView trong. Từng cách làm sẽ được nói trong các phần sau. 

ArrayAdapter(Context context, int resource, int textViewResourceId, T[] objects)

3. Custom ArrayAdapter 
Thông thường ở chế độ mặc định các item (hay các dòng) trong ListView chỉ hiển thị các dòng text. Để tùy biến các item của ListView trông đẹp hơn, lập trình viên có thể thêm các biểu tượng (icon), checkbox hoặc bất cứ cái gì vào item. Đơn giản chỉ là cung cấp dữ liệu cho adapter để tạo ra tập các đối tượng hiển thị (view objects) cho mỗi item.

public class MyAdapter extends ArrayAdapter {

public MyAdapter(Context context, int resource, int textViewResourceId, List objects) {
super(context, resource, textViewResourceId, objects);
}
@Override
public int getCount() {
return super.getCount();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
return super.getView(position, convertView, parent);
}
}

4. Simple Adapter
SimpleAdapter thì đúng như chữ simple – tức đơn giản. Nó là một Adapter đơn giản và dễ hiểu để ánh xạ dữ liệu vào những View được định nghĩa trong một tập tin XML. Bạn có thể chỉ rõ dữ liệu sẽ được đóng gói trong một danh sách như là một ArrayList của việc ánh xạ. Mỗi phần tử trong ArrayList là một thể hiện của một dòng trên ListView. Công việc ánh xạ này nó chứa dữ liệu cho mỗi dòng. Bạn cũng có thể chỉ rõ một tập tin XML chứa nhiều điều khiển (widget) mà được dùng để thể hiện một dòng và ta sẽ ánh xạ từng giá trị trong từng phần tử trong ArrayList sang từng widget nằm trên từng dòng. Gắn dữ liệu vào các Views xảy ra trong 2 giao đoạn. Sẽ được trình bày trong các phần sau.

SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)

5. Custom SimpleAdapter
Bất cứ khi nào chúng ta phải tạo một danh sách tùy chỉnh chúng ta cần phải thực hiện adapter tùy chỉnh. Như chúng ta đã thảo luận trước đó ArrayAdapter được sử dụng khi chúng ta có một danh sách các mục duy nhất được hỗ trợ bởi một Array. Vì vậy, nếu chúng ta cần tuỳ biến trong một ListView hoặc một GridView, chúng ta cần phải thực hiện Adapter đơn giản nhưng khi chúng ta cần nhiều tuỳ biến hơn trong ListView hoặc các GridView, chúng ta có nhiều lượt xem trong một mục trong danh sách và sau đó chúng ta phải thực hiện bất kỳ sự kiện nào như click hay bất kỳ sự kiện cho một view  thì chúng ta cần phải thực hiện một adapter tùy biến.

public class CustomAdapter extends SimpleAdapter {
public CustomAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) {
super(context, data, resource, from, to);

}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
return super.getView(position, convertView, parent);

}

@Override
public int getCount() {
return super.getCount();
}
}

Chú ý: Chúng tôi không thể thực hiện các sự kiện như click và các sự kiện khác trên mục con của một ListView  hoặc GridView. Nhưng chúng ta có thể làm đều đó thông qua SimpleAdapter