Tab Selector giống như Property Sheet trong Visual C, giống như Tab Control C#, hay trong Java:

– Tôi sẽ làm một ví dụ cụ thể về Tab Selector để bạn có thể thực hành lại và hiểu được vấn đề.
– Đối với Android, mỗi Tab bạn nên thiết kế trên một Layout khác
nhau, rồi trong Main Layout bạn include các tab đó vào (Tức là nếu như
ứng dụng bạn có 3 Tab con thì sẽ tạo 3 Layout khác nhau rồi include
chúng vào Main layout, chứ đừng thiết kế tất tần tật trong một Main
Layout nó sẽ gây khó khăn trong việc sửa lỗi ).
– Tôi trình bày sơ qua lý thuyết về Tab selector:
+ Tab selector gồm có 3 phần: Tab Host, Tab Widgets và FrameLayout.

+Tab Host: Là Container chính chứa các Tab buttons và Tab contents
+Tab Widget: Để định dạng cho các Tab buttons : Nhãn, Icon…
+FrameLayout: là Container để chứa các layout cho
Tab contents, ta chỉ có thể dùng FrameLayout cho Tab contents, không thể
dùng các loại Layout khác. Nếu bạn thắc mắc tại vì sao lại là
FrameLayout mà không phải là các Layout khác? thì Tôi chỉ nói đơn giản
thế này: Cho dù bạn có nhấn vào các Tab nào đi nữa thì layout tương ứng
với mỗi Tab mà bạn vừa nhấn vào cũng chỉ xuất hiện cùng một chỗ trên màn
hình điện thoại, điều này chỉ có FrameLayout mới giải quyết được.
*** Bây giờ bạn hãy xem hình minh họa về giao diện trong bài ví dụ Tab Selector của Tôi như sau:

– Như hình trên thì bạn thấy đó: Tab đầu tiên “1-CALCULATOR” là giao diện cho phép tính công trừ nhân chia, Tab thứ 2 “2-HISTORY” dùng để hiển thị danh sách các phép toàn đã thực hiện.
– Bạn xem cấu trúc tổng quan của ứng dụng:

-Vì ứng dụng của Tôi có 2 Tab nên Tôi sẽ tạo 2 tabs: tab1_layout.xml và tab2_layout.xml, 2 tabs này sẽ được include vào main layout activity_main.xml, vậy tổng cộng Tôi có 3 Layout.
– Ta vào xem main layout (activity_main.xml):
– xem Outline để dễ tưởng tượng:

-Còn đây là source XML:
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
| android:id = "@+id/LinearLayout1" android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" tools:context = ".MainActivity" > < TabHost android:id = "@android:id/tabhost" android:layout_width = "match_parent" android:layout_height = "match_parent" > < LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < TabWidget android:id = "@android:id/tabs" android:layout_width = "match_parent" android:layout_height = "wrap_content" > </ TabWidget > < FrameLayout android:id = "@android:id/tabcontent" android:layout_width = "match_parent" android:layout_height = "match_parent" > < LinearLayout android:id = "@+id/tab1" android:layout_width = "match_parent" android:layout_height = "match_parent" > < include layout = "@layout/tab1_layout" /> </ LinearLayout > < LinearLayout android:id = "@+id/tab2" android:layout_width = "match_parent" android:layout_height = "match_parent" > < include layout = "@layout/tab2_layout" /> </ LinearLayout > </ FrameLayout > </ LinearLayout > </ TabHost > </ LinearLayout > |
– Bạn nhìn vào dòng lệnh 30 và 36:
<include layout=”@layout/tab1_layout”/>
<include layout=”@layout/tab2_layout”/>
Đó chính là cách include một layout này vào trong một layout khác.
– Tiếp tục ta xem tab1_layout.xml, Tôi lấy lại bài tập trước về cộng trừ nhân chia:
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
| android:id = "@+id/TableLayout1" android:layout_width = "match_parent" android:layout_height = "match_parent" android:stretchColumns = "*" > < TableRow android:id = "@+id/tableRow1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView1" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "4" android:background = "#5B8020" android:gravity = "center" android:text = "Cộng trừ nhân chia" android:textColor = "#FFFFFF" android:textSize = "20sp" /> </ TableRow > < TableRow android:id = "@+id/tableRow2" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/textView2" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "Số a:" /> < EditText android:id = "@+id/editsoa" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "3" android:ems = "10" android:inputType = "number" > < requestFocus /> </ EditText > </ TableRow > < TableRow android:id = "@+id/tableRow3" 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 = "Số b:" /> < EditText android:id = "@+id/editsob" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "3" android:ems = "10" android:inputType = "number" /> </ TableRow > < TableRow android:id = "@+id/tableRow4" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < Button android:id = "@+id/btncong" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "+" /> < Button android:id = "@+id/btntru" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "-" /> < Button android:id = "@+id/btnnhan" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "*" /> < Button android:id = "@+id/btnchia" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:text = "/" /> </ TableRow > < TableRow android:id = "@+id/tableRow5" android:layout_width = "wrap_content" android:layout_height = "wrap_content" > < TextView android:id = "@+id/txtketqua" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:layout_span = "4" android:background = "#5B8020" android:textColor = "#FFFFFF" android:textSize = "25sp" /> </ TableRow > </ TableLayout > |
– Và xem tiếp tab2_layout.xml, đơn giản là chỉ có 1 ListView chứa danh sách các phép toán đã thực hiện bên Tab1:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <? xml version = "1.0" encoding = "utf-8" ?> android:layout_width = "match_parent" android:layout_height = "match_parent" android:orientation = "vertical" > < ListView android:id = "@+id/lvhistory" android:layout_width = "match_parent" android:layout_height = "wrap_content" > </ ListView > </ LinearLayout > |
– Giờ bạn xem MainActivity để biết được cách cấu hình Tabhost:
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
| package tranduythanh.com; import java.util.ArrayList; import android.os.Bundle; import android.app.Activity; import android.view.View; import android.view.View.OnClickListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.EditText; import android.widget.ListView; import android.widget.TabHost; import android.widget.TextView; import android.widget.Toast; public class MainActivity extends Activity { //Enum để thực hiện phép toán enum Operator { Cong, //phép cộng Tru, //phép trừ Nhan, //phép nhân Chia //phép chia } Button btncong,btntru,btnnhan,btnchia; EditText editsoa,editsob; TextView txtkq; ListView lvHistory; ArrayList<String>array_operator= new ArrayList<String>(); ArrayAdapter<String>adapter= null ; //Variable in listener OnClickListener myclick= new OnClickListener() { @Override public void onClick(View arg0) { switch (arg0.getId()) { case R.id.btncong: { processOperator(Operator.Cong); } break ; case R.id.btntru: { processOperator(Operator.Tru); } break ; case R.id.btnnhan: { processOperator(Operator.Nhan); } break ; case R.id.btnchia: { processOperator(Operator.Chia); } } } }; /** * Hàm xử lý phép toán theo operator * @param op */ public void processOperator(Operator op) { String sa=editsoa.getText()+ "" ; String sb=editsob.getText().toString(); int a=Integer.parseInt(sa); int b=Integer.parseInt(sb); String kq= "" ; switch (op) { case Cong: kq=a+ " + " +b + " = " +(a+b); break ; case Tru: kq=a+ " - " +b + " = " +(a-b); break ; case Nhan: kq=a+ " * " +b + " = " +(a*b); break ; case Chia: if (b!= 0 ) kq=a+ " / " +b + " = " +(a* 1.0 /b); else kq= "b phai khac 0" ; break ; default : kq= "Invalid operator!" ; } txtkq.setText(kq); array_operator.add(kq); adapter.notifyDataSetChanged(); } @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); loadTabs(); doFormWidgets(); } //Cấu hình tab public void loadTabs() { //Lấy Tabhost id ra trước (cái này của built - in android final TabHost tab=(TabHost) findViewById (android.R.id.tabhost); //gọi lệnh setup tab.setup(); TabHost.TabSpec spec; //Tạo tab1 spec=tab.newTabSpec( "t1" ); spec.setContent(R.id.tab1); spec.setIndicator( "1-Calculator" ); tab.addTab(spec); //Tạo tab2 spec=tab.newTabSpec( "t2" ); spec.setContent(R.id.tab2); spec.setIndicator( "2-History" ); tab.addTab(spec); //Thiết lập tab mặc định được chọn ban đầu là tab 0 tab.setCurrentTab( 0 ); //Ở đây Tôi để sự kiện này để các bạn tùy xử lý //Ví dụ tab1 chưa nhập thông tin xong mà lại qua tab 2 thì báo... tab.setOnTabChangedListener( new TabHost.OnTabChangeListener() { public void onTabChanged(String arg0) { String s= "Tab tag =" +arg0 + "; index =" + tab.getCurrentTab(); Toast.makeText(getApplicationContext(), s, Toast.LENGTH_LONG).show();} }); } //Khởi tạo các đối tượng và gán ADapter cho ListView public void doFormWidgets() { btncong=(Button) findViewById(R.id.btncong); btntru=(Button) findViewById(R.id.btntru); btnnhan=(Button) findViewById(R.id.btnnhan); btnchia=(Button) findViewById(R.id.btnchia); editsoa=(EditText) findViewById(R.id.editsoa); editsob=(EditText) findViewById(R.id.editsob); txtkq=(TextView) findViewById(R.id.txtketqua); lvHistory=(ListView) findViewById(R.id.lvhistory); btncong.setOnClickListener(myclick); btntru.setOnClickListener(myclick); btnnhan.setOnClickListener(myclick); btnchia.setOnClickListener(myclick); adapter= new ArrayAdapter<String> ( this , android.R.layout.simple_list_item_1, array_operator); lvHistory.setAdapter(adapter); } } |
– Tôi có giải thích sơ qua trong coding cách tạo tab, bạn hãy cố gắng làm lại để hiểu nó.
– Bao nhiêu tab không quan trọng, cuối cùng thì cũng chỉ đưa về xử lý bình thường như chỉ có 1 màn hình.
– Bạn có thể tải coding mẫu ở đây: http://adf.ly/1YyMpj
– Bài tập kế tiếp bạn sẽ học về Menu và Context menu, 2 control này rất ưa chuộng nên ta phải biết nó.
– Chúc bạn thành công.