Tuesday, March 29, 2016

Bài 21. Thực hành Gridview trong Android [Căn bản]

– Bài tập này bạn sẽ làm quen với control Gridview, cũng tương tự như ListView. Gridview cũng dựa vào Datasource và ArrayAdapter. ListView bạn làm như thế nào thì Gridview y xì.
– Điểm khác nhau là GridView có thiết lập số cột. Dữ liệu luôn đưa vào dưới dạng hình ống (mảng, list một chiều), nhưng dựa vào số cột ta thiết lập mà nó tự động ngắt hàng, xem hình minh họa:
19_grid_0 
– Bạn thấy đấy, Tôi có thể hiển thị Text hoặc hình ảnh vào GridView.
– Bạn có thể thiết lập số cột cho GridView theo hình dưới đây:
19_grid_1 

– Nếu bạn thiết lập android:numColumns=”3″,  Tức là Gridview sẽ ngắt dòng khi đủ 3 phần tử, nó chỉ khác chỗ này, còn việc đưa dữ liệu lên như thế nào thì nó y xì như làm với ListView.
– Ví dụ 1: Hiển thị văn bản lên GridView (xem hình Tôi đánh số 1):
– Bạn tạo một Android Project tên tùy thích, ở đây Tôi đặt tên: Vidu_Gridview_Text
– Đây là activity_main.xml cho ứng dụng:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/LinearLayout1"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical"
 tools:context=".MainActivity" >
 <TextView
 android:id="@+id/selection"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#8A9D6F"
 android:hint="Slected here" />
 <GridView
 android:id="@+id/gridView1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:numColumns="3" >
 </GridView>
</LinearLayout>
– Bạn xem dòng 15 là id của GridView, Tôi để mặc định gridView1
– Dòng 18 có thuộc tính: android:numColumns= “3”, tức là dữ liệu sẽ được hiển thị trong Gridview với định dạng 3 cột.
– Tiếp theo bạn xem MainActivity.java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package tranduythanh.com;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.TextView;
 
public class MainActivity extends Activity {
 
//Dùng mảng 1 chiều hoặc ArrayList để lưu một số dữ liệu
 String arr[]={"Ipad","Iphone","New Ipad",
 "SamSung","Nokia","Sony Ericson",
 "LG","Q-Mobile","HTC","Blackberry",
 "G Phone","FPT - Phone","HK Phone"
 };
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //Tối tượng này dùng để hiển thị phần tử được chọn trong GridView
 final TextView selection=(TextView)
 findViewById(R.id.selection);
 final GridView gv=(GridView) findViewById(R.id.gridView1);
 //Gán DataSource vào ArrayAdapter
 ArrayAdapter<String>da=new ArrayAdapter<String>
 (
 this,
 android.R.layout.simple_list_item_1,
 arr
 );
 //gán Datasource vào GridView
 gv.setAdapter(da);
 //Thiết lập sự kiện cho GridView,
 gv.setOnItemClickListener(new AdapterView
 .OnItemClickListener() {
 public void onItemClick(AdapterView<?> arg0,
 View arg1, int arg2,
 long arg3) {
 //Hiển thị phần tử được chọn trong GridView lên TextView
 selection.setText(arr[arg2]);
 }
 });
 }
}
– Bạn thấy đó, cách sử dụng GridView là y xì như ListView, nên nếu như bạn đã rành về ListView rồi thì GridView hiển nhiên bạn cũng làm tốt.
– Thực thi chương trình bạn sẽ thấy như hình bên dưới:

19_grid_3 

– Xem coding đầy đủ ở đây: http://adf.ly/1YuTFS
– Ví dụ 2 sẽ phức tạp hơn, hiển thị danh sách hình ảnh có sẵn lên GridView, mỗi lần chọn vào hình ảnh nào thì sẽ hiển thị chi tiết ảnh đó trên một màn hình mới:
– Có thể Demo này đã có nhiều website và Ebooks làm rồi, ở đây Tôi cũng muốn demo lại cho các bạn.
– Bạn xem giao diện của ứng dụng trước:
19_grid_5 
– Bên trái là màn hình chính cho phép hiển thị danh sách hình ảnh vào GridView, mỗi lần chọn vào từng hình trong GridView thì sẽ mở hình được chọn đó vào một màn hình mới (ví dụ như khi chọn hình chú Cừu thì nó sẽ hiển thị ra như màn hình bên phải ), nhấn nút Back để trở về màn hình chính.
– Ở đây có một sự khác biệt lớn đó là chúng ta chỉ sử dụng 1 MainActivity, không hề tạo thêm bất kỳ một Activity nào khác, chúng ta chỉ thay đổi Layout mà thôi. Nên nó cũng là điểm nhấn của ứng dụng.
-Hãy tạo một Android Project tên: Vidu_Gridview_DisplayImage và xem cấu trúc của chương trình:

19_grid_4 

-Layout sẽ có 2 cái: activity_main.xml là của màn hình chính dùng để hiển thị danh sách hình ảnh. solo_picture.xml là dùng để hiển thị từng hình riêng lẻ.
– Tạo thêm thư mục drawble và kéo thả một số hình ảnh vào.
–  Phần class có 2 class: MainActivity và MyImageAdapter kế thừa từ BaseAdapter.
– Bây giờ ta đi vào chi tiết của từng cái:
– activity_main.xml:
19_grid_6 

– Bạn có thể nhìn vào hình trên để làm hoặc tải coding mẫu ở bên dưới.
-solo_picture.xml:
19_grid_7 

– Bây giờ ta vào các class xử lý nghiệp vụ:

19_grid_8 

– Thứ nhất là class MyImageAdapter:
+ class này sẽ kế thừa từ BaseAdapter, và dùng để hiển thị từng hình ảnh riêng lẻ:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package tranduythanh.com;
 
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
/**
 * Class dùng để hiển thị từng hình ảnh riêng lẻ
 * @author drthanh
 *
 */
public class MyImageAdapter extends BaseAdapter {
 private Context mContext;
 private Integer []mThumbIds;
 public MyImageAdapter(Context c){
 mContext=c;
 }
 public MyImageAdapter(Context c,Integer []arrIds){
 mContext=c;
 mThumbIds=arrIds;
 }
 public int getCount()
 {
 return mThumbIds.length;
 }
 public Object getItem(int arg0)
 {
 return null;
 }
 public long getItemId(int arg0)
 {
 return 0;
 }
 /**
 * Cần override lại hàm này để hiển thị hình ảnh
 */
 public View getView(int arg0, View convertView, ViewGroup arg2) {
 ImageView imgView;
 if(convertView==null){
 imgView=new ImageView(mContext);
 //can chỉnh lại hình cho đẹp
 imgView.setLayoutParams(new GridView.LayoutParams(85, 85));
 imgView.setScaleType(ImageView.ScaleType.CENTER_CROP);
 imgView.setPadding(8, 8, 8, 8);
 }else{
 imgView=(ImageView) convertView;
 }
 //lấy đúng vị trí hình ảnh được chọn
 //gán lại ImageResource
 imgView.setImageResource(mThumbIds[arg0]);
 return imgView;
 }
}
– Thứ hai là class MainActivity:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package tranduythanh.com;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
 
public class MainActivity extends Activity
 implements OnItemClickListener
{
 TextView tvMsg;
 GridView gv;
 TextView tvSoloMsg;
 //mảng lưu danh sách các id hình ảnh có sẵn
 Integer[]mThumbIds;
 //Adapter cho GridView
 MyImageAdapter adapter=null;
 //Vì không tạo thêm 1 Activity nên lấy luôn 2 Id ở bên solo_picture.xml
 ImageView ivSoloPicture;
 Button btnBack;
 //Lưu Bundle backup cho MainActivity
 Bundle myBackupBundle;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 //Lưu savedInstanceState trước vào myBackupBundle
 myBackupBundle=savedInstanceState;
 setContentView(R.layout.activity_main);
 tvMsg=(TextView) findViewById(R.id.tvMsg);
 //gán mảng các Id hình ảnh cho mThumbIds
 mThumbIds=new Integer[]{R.drawable.image1,R.drawable.image2,
 R.drawable.image3,R.drawable.image4,
 R.drawable.image5,R.drawable.image6,
 R.drawable.ic_launcher,R.drawable.lifecycle};
 gv=(GridView) findViewById(R.id.gridView1);
 //thiết lập Datasource cho Adapter
 adapter=new MyImageAdapter(this, mThumbIds);
 //gán Adapter vào Gridview
 gv.setAdapter(adapter);
 //thiết lập sự kiện để mở từng hình ảnh chitiết
 gv.setOnItemClickListener(this);
 }
 public void onItemClick(AdapterView<?> arg0,
 View arg1, int arg2, long arg3) {
 //gọi hàm xem hình ảnh chi tiết tại ví trí thứ arg2
 showdetail(arg2);
 }
 public void showdetail(int posistion)
 {
 //Không mở Activity mới mà chỉ thiết lập lại Layout
 setContentView(R.layout.solo_picture);
 //Vừa gọi hàm trên thì màn hình sẽ thay đổi qua cái mới
 //ta lấy các control trong layout mới này
 tvSoloMsg=(TextView) findViewById(R.id.tvSoloMsg);
 tvSoloMsg.setText("Image at "+posistion);
 ivSoloPicture=(ImageView) findViewById(R.id.imgSolo);
 //thiết lập hình ảnh đang chọn lên ImageView mới
 ivSoloPicture.setImageResource(mThumbIds[posistion]);
 btnBack=(Button) findViewById(R.id.btnBack);
 //Thiết lập sự kiện click Back để phục hồi lại MainActivity
 //bằng cách gọi lại onCreate(myBackupBundle);
 btnBack.setOnClickListener(new View.OnClickListener() {
 public void onClick(View arg0) {
 onCreate(myBackupBundle);
 }
 });
 }
}
– Khởi chạy ứng dụng bạn sẽ có kết quả như mong muốn.
– Bài tập này bạn đã biết cách sử dụng GridView, biết cách đưa hình ảnh vào GridView, đặc biệt biết thêm một kỹ thuật mới đó là thay đổi Layout để đổi màn hình không cần chạy Activity.
– Ngoài ra còn biết thêm về BaseAdapter.
– Bạn có thể tải code mẫu đầy đủ ở đây: http://adf.ly/1YuTKX
– Bài tập tiếp theo bạn sẽ được thực hành về TimePickerDialog DatePickerDialog, 2 control này cũng đáng phải lưu tâm vì nó cũng dược sử dụng thường xuyên trong Android.
– Chúc các bạn thành công

No comments:

Post a Comment