Monday, March 28, 2016

bài 20.Cập nhật DataSource cho AutocompleteTextView lúc Runtime [Căn bản]

– 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.

18_auto_0 

– 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:

18_auto_3 

-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):

18_auto_1 

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

18_auto_2 

– 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
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 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"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 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ụ:
18_auto_4 

– 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