Trong bài này mình sẽ hướng dẫn các bạn customize một view thuộc nhóm List như: [url=http://android.vn/tags/listview/]ListView[/url] và ExpandableListView bằng cách sử dụng các [url=http://android.vn/tags/arrayadapter/]ArrayAdapter[/url] và dùng Cursor.

[b]ListView[/b]


[b]ListView using ArrayAdapter[/b]

Giả sử bây giờ ListView của bạn sẽ dùng để hiển thị danh sách các người bạn và trạng thái của họ.nên mỗi item của ListView lúc này sẽ phải hiển thị nhiều hơn 1 thông tin. nên việc sử dụng "[url=http://android.vn/tags/android/]android[/url].R.layout.simple_list_item_1" chắc là không đc rồi. vì "android.R.layout.simple_list_item_1" sẽ chỉ cho hiện 1 thông tin trên một dòng Text. Ở hướng dẫn sau đây tôi sẽ tùy chỉnh để mỗi item của ListView sẽ hiện lên 3 thông tin (Tên - String, Trạng Thái - String, và accept - boolean) các đối tượng của lớp Friend.
[list][*]Lớp Friend được mô tả như sau:[/list]

PHP:
[size=4]package com[/size].namnd.gingerbread;

import java.io.Serializable;

public class Friend implements Serializable{
private String nickName;
private String status;
private boolean checked;
public Friend(String nickName){
this.nickName = nickName;
this.setChecked(false);
}
public String getNickName(){
return this.nickName;
}
public void setStatus(String status) {
this.status = status;
}
public String getStatus() {
return this.status;
}
public void setChecked(boolean checked) {
this.checked = checked;
}
public boolean isChecked() {
return this.checked;
}
@Override
public boolean equals(Object o) {
// TODO Auto-generated method stub
if(o instanceof Friend) {
Friend f = (Friend)o;
return this.nickName.equalsIgnoreCase(f.getNickName());
}
return false;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.nickName.hashCode();
}
}

[list][*]Sửa file main.xml như sau:[/list]

PHP:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@+id/listfriend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
/>
</LinearLayout>

[list][*]trong res/layout ta thêm 1 file tên là listview.xml với nội dung sau:[/list]

PHP:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<CheckBox
android:id="@+id/_check_nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
androidaddingTop="20px"
androidaddingRight="10px"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
androidrientation ="vertical"
>
<TextView
android:id="@+id/_nickname"
android:textSize = "15px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:lines="1"
android:textStyle="bold"
android:textColor="#ff0099"
/>
<TextView
android:id="@+id/_status"
android:textSize="13px"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:lines="1"
android:textColor="#99ff00"
/>
</LinearLayout>
</LinearLayout>

[list][*]file listview.xml sẽ tạo ra giao diện cách bố trí cho 1 item của ListView[/list]Thêm lớp CustomViewFriend trong package com.namnd.gingerbread ở trên. lớp này dùng để load giao diện trong file listview.xml nội dung như sau:


PHP:
[size=4]package com[/size].namnd.gingerbread;

import android.content.Context;
import android.view.LayoutInflater;
import android.widget.CheckBox;
import android.widget.LinearLayout;
import android.widget.TextView;

public class CustomViewFriend extends LinearLayout {
CheckBox checkBox;
TextView tvNickName;
TextView tvStatus;
Context context;
public CustomViewFriend(Context context) {
super(context);
// TODO Auto-generated constructor stub
// su dung LayoutInflater de gan giao dien trong listview.xml
this.context = context;
LayoutInflater li = (LayoutInflater)this.getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
li.inflate(R.layout.listview, this,true);

checkBox = (CheckBox)findViewById(R.id._check_nick);
tvNickName= (TextView)findViewById(R.id._nickname);
tvStatus = (TextView)findViewById(R.id._status);
}
}

[list][*]CustomViewFriend của chúng ta ở đây khá đơn giản, đó là 1 LinearLayout chứa 2 thành phần: 1 CheckBox và 1 LinearLayout khác gồm 2 TextView để hiển thị nickName và status. Sau đó ta thêm 1 lớp có tên ListFriendAdapter cũng trong package trên, lớp này kế thừa từ lớp ArrayAdapter. ListFriendAdapter sẽ được sử dụng thay thế cho ArrayAdapter để bind với ListView. Thông thường ArrayAdapter chỉ cho hiển thị String bằng TextView, nhưng với việc kế thừa và override phương thức getView, ta có thể định nghĩa lại hiển thị cho các thành phần của ListView.[/list]

PHP:
[size=4]package com[/size].namnd.gingerbread;

import java.util.ArrayList;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.TextView;

public class ListFriendAdapter extends ArrayAdapter<Friend>{
ArrayList<Friend> array;
int resource;
CheckBox check;
TextView tvNickName;
TextView tvStatus;
Context context;
Friend friend;

public ListFriendAdapter(Context context, int textViewResourceId,ArrayList<Friend> array) {
super(context, textViewResourceId,array);
// TODO Auto-generated constructor stub

this.context = context;
this.resource = textViewResourceId;
this.array = array;
}
//Phương thức xác định View mà Adapter hiển thị, ở đây chính là CustomViewFriend
public View getView(int position, View convertView, ViewGroup parent){
View friendView = convertView;
if(friendView ==null ){
friendView = new CustomViewFriend(getContext());
}
friend = array.get(position);
if(friend !=null){
tvNickName = ((CustomViewFriend)friendView).tvNickName;
tvStatus = ((CustomViewFriend)friendView).tvStatus;
check =((CustomViewFriend)friendView).checkBox;
// lay doi tuong friend va dua ra UI
tvNickName.setText(friend.getNickName());
tvStatus.setText(friend.getStatus());
check.setChecked(friend.isChecked());
}
return friendView;
}

}

Và việc cuối cùng cần làm là viết lại Activity. Tới ListDemo.java (extends Activity) và chỉnh sửa theo nội dung sau:


PHP:
[size=4]package com[/size].namnd.gingerbread;

import java.util.ArrayList;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;

public class ListDemo extends Activity {

private static final int LOGOUT = Menu.FIRST;
private static final int CHANGE = Menu.FIRST+2;
private static final int EXIT = Menu.FIRST+6;
private static final int ABOUT = Menu.FIRST+4;

ArrayList<Friend> array;
ListFriendAdapter arrayAdapter;
ListView list;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
list = (ListView)findViewById(R.id.listfriend);
array = new ArrayList<Friend>();
arrayAdapter = new ListFriendAdapter(this, R.layout.listview, array);

list.setAdapter(arrayAdapter);
Friend f = new Friend("namd");
f.setStatus("Có ai thích tắm nước mắm không?");
f.setChecked(true);
this.addNick(f);
this.addNick( f= new Friend("MungTV"));
this.addNick(new Friend("TuyenHL"));
f.setStatus("nước mắm thơm quá đi mất");
this.addNick(f = new Friend("QuangLH"));
f.setStatus("được tắm nước mắm thật sảng khoái quá đi mất! ");
f.setChecked(true);
this.addNick(f = new Friend("TuanPV"));
f.setStatus("miễn bàn, tuy thích nhưng chắc không được");
}
// tao Option Menu
public boolean onCreateOptionsMenu(Menu menu){
super.onCreateOptionsMenu(menu);
menu.add(0,LOGOUT,0,"LogOut").setIcon(android.R.drawable.ic_menu_revert);
menu.add(0,CHANGE,0,"Change Password").setIcon(android.R.drawable.ic_menu_edit);
menu.add(0,ABOUT,0,"About").setIcon(android.R.drawable.ic_menu_info_details);
menu.add(0,EXIT,0,"Exit").setIcon(android.R.drawable.ic_menu_close_clear_cancel);
return true;
}
// xu ly cac su kien cho menu
public boolean onOptionsItemSelected(MenuItem item){

return true;
}

public void addNick(Friend friend){
array.add(0,friend);
arrayAdapter.notifyDataSetChanged();
}
}

Các bạn có thể lưu ý là thay vì sử dụng ArrayList<String> như trước mình đã thay bằng ArrayList<Friend> và trong khởi tạo đối tượng arrayAdapter thì đối số thứ 2 là R.layout.listview thay vì android.R.layout.simple_list_item_1, nghĩa là chúng ta đã sử dụng layout do mình tự tạo thay vì layout Android cung cấp sẵn cho hiển thị các thành phần của ListView. Kết quả khi chương trình chạy như sau:

[img]http://android.vn/attachments/10193/[/img]

[url=http://android.vn/tags/listview/]listview[/url], [url=http://android.vn/tags/?t=custom+listview]custom listview[/url], [url=http://android.vn/tags/android/]android[/url], [url=http://android.vn/tags/arrayadapter/]arrayadapter[/url]