Bài 4: THIẾT KẾ GIAO DIỆN NGƯỜI DÙNG VỚI CÁC VIEW CƠ BẢN
4.3. Hiển thị ảnh với ImageView và Gallery
Ảnh là đối tượng được sử dụng rất tích cực trong các ứng dụng hiện đại. Trong phần này ta sẽ tìm hiểu cách hiển thị ảnh trong Android với ImageView và hiển thị danh sách ảnh với Gallery view.
Ta sẽ xem xét 2 loại view này trong một ví dụ tương đối điển hình: hiển thị danh sách ảnh cho phép người dùng cuộn và chọn ảnh cần xem. Ảnh được chọn sẽ được hiển thị to hơn ở bên dưới.
Trước tiên ta chuẩn bị một số ảnh cho dự án này
Trong mã nguồn, các ảnh này sẽ được truy cập thông qua id của nó trong lớp R (resource):
R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5, R.drawable.pic6, R.drawable.pic7
Layout của activity cho ví dụ này như sau:
<?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"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Images of San Francisco" />
<Gallery
android:id="@+id/gallery1"
62 android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/image1"
android:layout_width="320dp"
android:layout_height="250dp"
android:scaleType="fitXY" />
</LinearLayout>
Mã nguồn của activity này như sau:
public class GalleryActivity extends Activity { //---the images to display--- Integer[] imageIDs = { R.drawable.pic1,
R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5, R.drawable.pic6, R.drawable.pic7 };
/** Called when the activity is first created. */ @Override
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Gallery gallery = (Gallery) findViewById(R.id.gallery1);
gallery.setAdapter(new ImageAdapter(this)); gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id)
{
Toast.makeText(getBaseContext(),
"pic" + (position + 1) + " selected", Toast.LENGTH_SHORT).show();
//---display the images selected---
ImageView imageView = (ImageView) findViewById(R.id.image1);
imageView.setImageResource(imageIDs[position]);
} });
}
public class ImageAdapter extends BaseAdapter { Context context;
int itemBackground;
public ImageAdapter(Context c) {
context = c;
//---setting the style---
63
TypedArray a = obtainStyledAttributes(R.styleable.Gallery1);
itemBackground = a.getResourceId(
R.styleable.Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
//---returns the number of images--- public int getCount() {
return imageIDs.length;
}
//---returns the item---
public Object getItem(int position) { return position;
}
//---returns the ID of an item---
public long getItemId(int position) { return position;
}
//---returns an ImageView view---
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(context);
imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));
} else {
imageView = (ImageView) convertView;
}
imageView.setBackgroundResource(itemBackground); return imageView;
} } }
Sau khi chạy ứng dụng, ta sẽ quan sát thấy danh sách các ảnh nhỏ ở phía trên cùng của activity, ta có thể cuộn ngang danh sách này để chọn ảnh muốn xem, ảnh được chọn sẽ luôn được căn giữa trong Gallery. Sau khi được chọn, ảnh to sẽ được hiển thị bên dưới (xem hình minh họa bên dưới).
64
Ta cần giải thích thêm một chút về đoạn mã nguồn của Activity phía trên. Đầu tiên, ta lưu danh sách ID của các ảnh cần thêm vào Gallery:
Integer[] imageIDs = { R.drawable.pic1, R.drawable.pic2, R.drawable.pic3, R.drawable.pic4, R.drawable.pic5, R.drawable.pic6, R.drawable.pic7 };
Sau đó, để thêm các ảnh này vào Gallery, ta cần một lớp trung gian, gọi là adapter. Adapter này sẽ cung cấp nguồn nội dung cho các đối tượng gồm nhiều phần tử như Gallery hay các danh sách. Ta sẽ xem chi tiết adapter này ở phía dưới. Để gắn adapter này vào gallery, ta dùng hàm setAdapter:
gallery.setAdapter(new ImageAdapter(this));
Khi một ảnh trong gallery được chọn, ta sẽ hiển thị ảnh to phía dưới, để làm việc này, ta cần thêm hàm xử lý sự kiện onItemClick của gallery:
gallery.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
Toast.makeText(getBaseContext(),
65
"pic" + (position + 1) + " selected", Toast.LENGTH_SHORT).show();
//---display the images selected---
ImageView imageView = (ImageView) findViewById(R.id.image1);
imageView.setImageResource(imageIDs[position]);
} });
Mỗi lớp adapter cho các view nhiều đối tượng (như gallery) cần kế thừa từ lớp BaseAdapter và cần nạp chồng các phương thức sau:
public class ImageAdapter extends BaseAdapter { public ImageAdapter(Context c){ … }
public int getCount(){ … }
public Object getItem(int position) { … } public long getItemId(int position) { … } public View getView(int position, View convertView, ViewGroup parent) {…}
}
Trong đó hàm getView trả về view của đối tượng con (item) trong danh sách, tại vị trí position.
Một số view sử dụng Adapter làm nguồn dữ liệu trong Android có thể kể đến như:
➤ ListView: danh sách các đối tượng (theo chiều dọc) GridView: danh sách các đối tượng dạng bảng (nhiều cột, cuốn theo chiều dọc)
➤ Spinner: danh sách xổ xuống (giống khái niệm combo box trong lập trình web)
➤ Gallery: thư viện ảnh như ví dụ ở trên
Android cũng định nghĩa sẵn một số lớp con của lớp BasicAdapter như:
➤ ListAdapter
➤ ArrayAdapter
➤ CursorAdapter
➤ SpinnerAdapter
Chúng ta sẽ tìm hiểu một số lớp trong số đó trong phần còn lại của giáo trình.