– Trong bài 19 bạn đã biết cách sử dụng AutocompleteTextView và MultiAutocompleteTextView nhưng DataSource được cố định sẵn trong Coding. Bài tập này Bạn sẽ học cách cập nhật DataSource lúc ứng dụng đang chạy (runtime).
– Tôi sẽ có một ví dụ cụ thể để bạn thực hành về trường hợp này, bạn
hãy tập trung theo dõi và thực hành lại. Tôi nghĩ bài này rất thú vị.
– Bây giờ bạn mở AVD lên và nhấn tổ hợp phím ctrl+ F11 để xoay ngang màn hình, Tôi sẽ làm ví dụ về màn hình nằm ngang.

–
Bạn xem màn hình trên Tôi chia ra làm 2. Bên trái cho phép nhập thông
tin sinh viên, bên phải cho phép hiển thị danh sách sinh viên đã nhập.
Bạn chú ý là ListView Tôi làm là Custom Layout (Mỗi dòng Lớn có 2 loại
dữ liệu: mã và tên cùng 1 dòng. giới tính, năm sinh, quê quán cùng 1
dòng và chữ nhỏ hơn có màu đó in nghiêng).
– Ngày sinh dùng DatePickerDialog
– Nơi sinh dùng AutoCompleteTextView. Mỗi lần nhấn “Nhập Sv”
thì chương trình sẽ cập nhật động nơi sinh vào DataSource của nó, chú ý
là không cho phép trùng lắp. Trong các lần nhập nơi sinh tiếp theo thì
nó phải tự động lọc giúp người sử dụng nhập lẹ hơn.
– Ta bắt đầu vào chi tiết ứng dụng.
1- Đây là cấu trúc thư mục trong ứng dụng:

-Nhìn vào cấu trúc thì bạn thấy có 2 Layout, layout chính là activity_main.xml, còn layout sinhvien_item_layout.xml là Tôi dùng để custom lại ListView (nó sẽ được xử lý trong class MyArrayAdapter).
2- Thiết kế giao diện với màn hình nằm ngang (xem hình):

– Dưới đây là Outline activity_main.xml:

–
Nếu như nhìn vào Outline mà bạn có thể thiết kế được giao diện như trên
thì Tôi nghĩ bạn đã thật sự hiểu về Layout, tuy nhiên Tôi vẫn cung cấp
Source XML, bạn xem tham khảo
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
| android:id = "@+id/LinearLayout1" android:layout_width = "match_parent" android:layout_height = "match_parent" tools:context = ".MainActivity" > < LinearLayout android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:background = "#FFF0E1" android:orientation = "vertical" > < TextView android:id = "@+id/textView1" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:background = "#008000" android:text = "Nhập Thông Tin Sinh Viên:" android:textColor = "#FFFFFF" /> < TableLayout android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TableRow android:id = "@+id/tableRow2" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView3" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Mã:" /> < EditText android:id = "@+id/editMa" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "2" > < requestFocus /> </ EditText > </ TableRow > < TableRow android:id = "@+id/tableRow3" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView4" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Tên:" /> < EditText android:id = "@+id/editTen" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "2" /> </ TableRow > < TableRow android:id = "@+id/tableRow4" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView5" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Giới tính:" /> < CheckBox android:id = "@+id/chkGt" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "2" android:text = "Là Nữ" /> </ TableRow > < TableRow android:id = "@+id/tableRow5" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView6" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Ngày sinh:" /> < EditText android:id = "@+id/editNgaySinh" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:inputType = "date" android:text = "25/09/1989" /> < Button android:id = "@+id/btnNgaySinh" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "..." /> </ TableRow > < TableRow android:id = "@+id/tableRow6" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView7" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Nơi sinh:" /> < AutoCompleteTextView android:id = "@+id/autoCompleteNS" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:completionThreshold = "1" android:layout_span = "2" android:ems = "10" /> </ TableRow > < TableRow android:id = "@+id/tableRow7" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < Button android:id = "@+id/btnNhap" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_column = "1" android:gravity = "center" android:text = "Nhập SV" /> </ TableRow > </ TableLayout > </ LinearLayout > < LinearLayout android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_weight = "1" android:background = "#EAEAEA" android:orientation = "vertical" > < TextView android:id = "@+id/textView2" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:background = "#000040" android:text = "Danh Sách Sinh Viên:" android:textColor = "#FFFFFF" /> < ListView android:id = "@+id/lvsinhvien" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_weight = "1" > </ ListView > </ LinearLayout > </ LinearLayout > |
– còn đây là của sinhvien_item_layout.xml:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| <? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < TextView android:id = "@+id/txtMaVaTen" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:textSize = "15sp" /> < TextView android:id = "@+id/txtThongTinKhac" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:textColor = "#800000" android:textSize = "10sp" android:textStyle = "italic" /> </ LinearLayout > |
-3 -Bạn xem cấu trúc class xử lý nghiệp vụ:

– class Student:
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
| package tranduythanh.com; import java.util.Date; /** * Class dùng để lưu trữ thông tin của sinh viên * id: Mã * name: Tên * gender: giới tính, true là nữ * birthday: lưu năm sinh * placeOfBirth: nơi sinh * @author drthanh * */ public class Student { private String id; private String name; private boolean gender; private Date birthday; private String placeOfBirth; public String getId() { return id; } public void setId(String id) { this .id = id; } public String getName() { return name; } public void setName(String name) { this .name = name; } public boolean isGender() { return gender; } public void setGender( boolean gender) { this .gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this .birthday = birthday; } public String getPlaceOfBirth() { return placeOfBirth; } public void setPlaceOfBirth(String placeOfBirth) { this .placeOfBirth = placeOfBirth; } public Student(String id, String name, boolean gender, Date birthday, String placeOfBirth) { super (); this .id = id; this .name = name; this .gender = gender; this .birthday = birthday; this .placeOfBirth = placeOfBirth; } public Student() { super (); } } |
– 4 class MyArrayAdapter (class dùng để Custom Listview):
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
| package tranduythanh.com; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Locale; import android.app.Activity; import android.view.View; import android.view.ViewGroup; import android.widget.ArrayAdapter; import android.widget.TextView; /** * Đây là class dùng để custom layout * Bạn đã được học trước đó * Class này sẽ lấy layout: sinhvien_item_layout.xml * @author drthanh * */ public class MyArrayAdapter extends ArrayAdapter<Student> { Activity context; int resourceId; ArrayList<Student>arrStudent; public MyArrayAdapter(Activity context, int resource, ArrayList<Student> objects) { super (context, resource, objects); this .context=context; this .resourceId=resource; this .arrStudent=objects; } @Override public View getView( int position, View convertView, ViewGroup parent) { if (convertView== null ) { //gắn Layout vào Activity convertView= context.getLayoutInflater().inflate(resourceId, null ); } //Lấy Textview để lưu mã và tên TextView txtMaTen=(TextView) convertView.findViewById(R.id.txtMaVaTen); //Lấy TextView để lưu giới tính, năm sinh, nơi sinh TextView txtKhac=(TextView) convertView.findViewById(R.id.txtThongTinKhac); //Lấy sinh viên thứ position Student s=arrStudent.get(position); txtMaTen.setText(s.getId()+ " - " +s.getName()); //Dùng SimpleDateFormat để định dạng ngày tháng dd/MM/YYYY -> 22/12/2012 SimpleDateFormat dft= new SimpleDateFormat( "dd/MM/yyyy" ,Locale.getDefault()); txtKhac.setText((s.isGender()? "Nữ-" : "Nam-" )+ dft.format(s.getBirthday())+ " - " + s.getPlaceOfBirth()); return convertView; } } |
-5- class MainActivity để xử lý nghiệp vụ:
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
| package tranduythanh.com; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Locale; import android.os.Bundle; import android.app.Activity; import android.app.DatePickerDialog; import android.app.DatePickerDialog.OnDateSetListener; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.AutoCompleteTextView; import android.widget.Button; import android.widget.CheckBox; import android.widget.DatePicker; import android.widget.EditText; import android.widget.ListView; import android.widget.Toast; public class MainActivity extends Activity { ListView lvSinhvien; //Cặp đôi để Custom ListView MyArrayAdapter adapterSinhvien; ArrayList<Student> arrSinhvien= new ArrayList<Student>(); EditText editMa,editTen,editNamsinh; CheckBox chkGender; Button btnNamsinh,btnNhapsv; AutoCompleteTextView autoTextNs; //Cặp đôi để dùng cho AutoCompleteTextView ArrayList<String>arrAuto= new ArrayList<String>(); ArrayAdapter<String>adapterAuto; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); getFormWidgets(); addEventsForWidgets(); //fakeData(); } /** * hàm lấy các widgets */ public void getFormWidgets() { editMa=(EditText) findViewById(R.id.editMa); editTen=(EditText) findViewById(R.id.editTen); editNamsinh=(EditText) findViewById(R.id.editNgaySinh); chkGender=(CheckBox) findViewById(R.id.chkGt); autoTextNs=(AutoCompleteTextView) findViewById(R.id.autoCompleteNS); btnNamsinh=(Button) findViewById(R.id.btnNgaySinh); btnNhapsv=(Button) findViewById(R.id.btnNhap); lvSinhvien=(ListView) findViewById(R.id.lvsinhvien); //Gán DataSource cho Adapter ListView adapterSinhvien= new MyArrayAdapter( this , R.layout.sinhvien_item_layout, arrSinhvien); //Gán Adapter vào ListView lvSinhvien.setAdapter(adapterSinhvien); } /** * Hàm thiết lập sự kiện cho Button */ public void addEventsForWidgets() { btnNamsinh.setOnClickListener( new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub processBirthday(); } }); btnNhapsv.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { processInput(); } }); } /** * Hàm hiển thị DatePickerDialog để chọn năm sinh */ public void processBirthday() { OnDateSetListener callBack= new OnDateSetListener() { @Override public void onDateSet(DatePicker arg0, int arg1, int arg2, int arg3) { editNamsinh.setText(arg3+ "/" +arg2+ "/" +arg1); } }; //Ở đây Tôi chưa xử lý lấy ngày tháng năm trên EditText đưa vào DatePicker //Bạn tự làm DatePickerDialog dateDialog= new DatePickerDialog( this , callBack, 1989 , 9 , 25 ); dateDialog.setTitle( "Birthday" ); dateDialog.show(); } /** * Hàm xử lý nhập dữ liệu từ giao diện */ public void processInput() { String ma=editMa.getText()+ "" ; String ten=editTen.getText()+ "" ; String ns=editNamsinh.getText()+ "" ; String nois=autoTextNs.getText()+ "" ; boolean gt=chkGender.isSelected(); SimpleDateFormat dft= new SimpleDateFormat( "dd/MM/yyyy" ,Locale.getDefault()); try { Student s= new Student(ma, ten, gt, dft.parse(ns), nois); arrSinhvien.add(s); //Thêm mới xong thì gọi hàm dưới cập nhập lại giao diện adapterSinhvien.notifyDataSetChanged(); //Xử lý cho Autocomplete về nơi sinh processAutoComplete(nois); } catch (ParseException e) { Toast.makeText( this , e.toString(), Toast.LENGTH_LONG).show(); } } /** * Hàm xử lý Autocomplete Nơi sinh * @param data */ public void processAutoComplete(String data) { //Chạy từ đầu chí cuối nếu trùng thì thoát khỏi hàm for ( int i= 0 ;i<arrAuto.size();i++) { String x=arrAuto.get(i); if (x.trim().equalsIgnoreCase(data.trim())) return ; } //nếu xuống đây được tức là chưa tồn tại-> đừa vào arrAuto arrAuto.add(data); //Đưa vào ADapter adapterAuto= new ArrayAdapter<String>( this , android.R.layout.simple_list_item_1, arrAuto); //đưa Adapter vào AutoComplete autoTextNs.setAdapter(adapterAuto); } public void fakeData() { Student s1= new Student( "1" , "Đoàn Ái Nương" , true , new Date( 1980 - 1900 , 2 , 2 ), "TP. Hồ Chí Minh" ); Student s2= new Student( "2" , "Nguyễn Thùy Trang" , true , new Date( 1982 - 1900 , 3 , 3 ), "Lâm Đồng" ); Student s3= new Student( "3" , "Hoàng Văn Phúc" , false , new Date( 1970 - 1900 , 4 , 4 ), "Hà Nội" ); Student s4= new Student( "4" , "Đinh Hồng Lợi" , false , new Date( 1972 - 1900 , 4 , 4 ), "Bắc Giang" ); Student s5= new Student( "5" , "Nguyễn Hoàng Uyên" , true , new Date( 1970 - 1900 , 4 , 4 ), "Huê" ); arrSinhvien.add(s1); arrSinhvien.add(s2); arrSinhvien.add(s3); arrSinhvien.add(s4); arrSinhvien.add(s5); adapterSinhvien.notifyDataSetChanged(); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.activity_main, menu); return true ; } } |
– Bạn xem Tôi giải thích trong coding luôn rồi.
– Chú ý là bạn có thể yêu cầu ứng dụng chạy theo màn hình nằm ngang trong code (bạn viết trong onCreate):
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
– Bạn hãy cố gắng làm bài này vì Tôi cảm thấy nó rất hay về ý tưởng thiết kế và kỹ thuật lập trình.
– Bạn có thể Tải code mẫu tại đây: http://adf.ly/1YqHRt
– Bài tập tiếp theo bạn sẽ được thực hành về GridView, một control cũng cần phải lưu tâm.
– Chúc bạn thành công
No comments:
Post a Comment