Bài tập 13: Thực hành về ListView trong Android

Nếu bạn nào muốn rèn luyện thêm lập trình Java, lập trình Android, lập trình Webservice với tổng thời lượng học >80 giờ thì có thể đăng ký học theo các link sau:

1) Lập trình java trong 4 tuần – 19 giờ(chỉ dành cho những ai CHƯA BIẾT GÌ VỀ LẬP TRÌNH hoặc đã biết lơ mơ về Java, lý thuyết và các bài tập phong phú tạo nền tảng lập trình Android và các hướng khác liên quan tới Java):
https://kyna.vn/lap-trinh-java-trong-4-tuan/325931
2) Lập trình Android cơ bản (>24 giờ học) – toàn bộ kiến thức về Android cơ bản:
https://kyna.vn/lap-trinh-android-co-ban/325931
3) Lập trình Android nâng cao (23 giờ học) – toàn bộ kiến thức về Android nâng cao:
https://kyna.vn/lap-trinh-android-nang-cao/325931
4) Lập trình Webservice cho Di Động – 14 giờ (dành cho những ai ĐÃ BIẾT ANDROID), những ai chưa biết Android tuyệt đối không đăng ký, khóa học hướng dẫn tỉ mỉ từ A->Z để có thể xây dựng được một phần mềm hoàn chỉnh tương tác client-server:
https://kyna.vn/lap-trinh-webservice-cho-di-dong/325931

[polldaddy poll=9764234]

Trong các bài tập trước các bạn đã được làm quen với nhiều control cơ bản, bài tập này bạn sẽ được làm quen với control nâng cao, cụ thể là ListView. Trong ứng dụng cần lưu trữ và hiển thị danh sách các thông tin đa phần chúng ta sài control ListView. Hiện tại bạn chỉ cần biết sử dụng ListView có sẵn của Android là được rồi, trong các bài tập tiếp theo Tôi sẽ hướng dẫn các bạn Custom Layout lại ListView (tự làm mới ListView theo ý mình).

– Bài tập này Tôi sẽ cung cấp nhiều cách hành xử với ListView, ứng với mỗi cách là có các ví dụ mẫu khác nhau, vì vậy các bạn nên cố gắng theo dõi và thực hành lại những ví dụ.

– Bạn hãy thực hành tốt 5 trường hợp Tôi trình bày dưới đây:

1) Trường hợp 1:– Sử dụng ListView control với mảng dữ liệu định sẵn.

-Trường hợp này Tôi đưa ra một ví dụ đơn giản là cho phép hiển thị mảng dữ liệu lên trên ListView, bạn xem hình minh họa:

13_lv_0

– Giao diện trên có 2 control:

+ListView : dùng để hiển thị mảng dữ liệu

+TextView có màu xanh lục: Dùng để hiển thị vị trí và giá trị của phần tử được chọn trong ListView

– Bạn tạo một Android Project tên là : Vidu_ListView_HardCode_Array, chọn layout phù hợp và kéo thả các control vào giao diện:

13_lv_1– Dưới đây là nội dung của activity_main.xml:

[code language=”xml”]

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" >
<TextView android:id="@+id/txtselection" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#dd0230dd" android:hint="Selected person here" />
<ListView android:id="@+id/lvperson" android:layout_width="match_parent" android:layout_height="wrap_content" >
</ListView>
</LinearLayout>

[/code]

-Đặt id cho Listview là lvperson (nhìn dòng lệnh 15 ở trên), bạn có thể định dạng thêm một số đặc tính khác nhưng trong bài tập này thì chưa cần thiết, chỉ cần hiển thị được dữ liệu lên giao diện là đã đạt yêu cầu.

– Bây giờ bạn mở MainActivity.java lên để viết code:

[code language=”java”]

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.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1. Khởi tạo dữ liệu cho mảng arr (còn gọi là data source)
final String arr[]={"Teo","Ty","Bin","Bo"};
//2. Lấy đối tượng Listview dựa vào id
ListView lv=(ListView) findViewById(R.id.lvperson);
//3. Gán Data source vào ArrayAdapter
ArrayAdapter<String>adapter=new ArrayAdapter<String>
(this, android.R.layout.simple_list_item_1, arr);
//4. Đưa Data source vào ListView
lv.setAdapter(adapter);
final TextView txt=(TextView) findViewById(R.id.txtselection);
//5. Thiết lập sự kiện cho Listview, khi chọn phần tử nào thì hiển thị lên TextView
lv.setOnItemClickListener(
new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0,
View arg1,
int arg2,
long arg3) {
//đối số arg2 là vị trí phần tử trong Data Source (arr)
txt.setText("position :"+arg2+" ; value ="+arr[arg2]);
}
});
}
}

[/code]

– Tôi đã giải thích từng dòng lệnh ở bên trong code, giờ Tôi giải thích thêm về ArrayAdapter, bạn nhìn vào dòng lệnh 21.

ArrayAdapter<String>adapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, arr);

– Dữ liệu từ Data source (arr) sẽ được gắn vào  ArrayAdapter, ArrayAdapter sẽ gắn vào ListView.

– Bạn nhìn vào đối số đầu tiên của constructor ArrayAdapter : this, chính là context của Activity hiện tại, bạn có thể viết MainActivity.this (nếu bạn viết như thế này thì ở bất kỳ vị trí nào nó cũng hiểu là context của MainActivity, do đó các bạn nên viết như thế này để bạn có thể copy paste nó tới bất kỳ vị trí nào thì nó cũng hiểu)

– Đối số thứ 2 android.R.layout.simple_list_item_1 : bạn để ý  android Tôi tô màu xanh, đây chính là layout Listview mà được Android xây dựng sẵn, các bài tập kế tiếp ta sẽ tự xây dựng mà không sử dụng cái có sẵn này. Như vậy thì simple_list_item_1 lưu ở đâu? và bên trong nó như thế nào?. Nó được lưu trong SDK/platforms/android-api (x)/data/res/layout/simple_list_item_1.xml. Bạn có thể xem nội dung và vị trí của layout này một cách nhanh chóng bằng  đè phím Ctrl + click chuột vào dòng lệnh này, bạn sẽ thấy như bên dưới:

13_lv_2– Đối số thứ 3: chính là arr (data source), bạn có thể truyền vào ArrayList.

– Nhìn vào dòng lệnh 27 chỗ gán sự kiện cho ListView (bạn nhớ là chỉ cần gõ một vài ký tự đầu rồi nhấn Ctrl+ Space Bar thì các lệnh đằng sau sẽ tự động xuất hiện ra cho bạn):

+ Ta có interface AdapterView.OnItemClickListener, nó dùng để thiết lập sự kiện cho ListView, interface này có 1 phương thức trừu tượng là onItemClick nên ta override nó về xử lý trong này. Bạn cũng nhớ là chỗ này không có gõ bằng tay mà chỉ cần nhấn tổ hợp phím Ctrl + 1 chọn add unimplement method là nó tự xuất hiện. Ngoài ra nó còn nhiều sự kiện khác các bạn tự tìm hiểu thêm.

Bạn có thể tải code đầy đủ ở đây:http://www.mediafire.com/?uwy4lp0e1jt0mik

2) Trường  hợp 2: Sử dụng ListView với mảng dữ liệu được lưu trong Xml:

– Giao diện và xử lý sự kiện trong trường hợp này là y xì trường hợp 1. Chỉ khác ở chỗ là dữ liệu sẽ được load từ XML, nên Tôi chỉ hướng dẫn cách tạo String – Array trong XML và  cách load String-Array trong coding như thế nào.

– Bạn tạo một Android Project tên là: Vidu_ListView_Xml_Array

Để tạo String – Array trong XML bạn làm như sau:

Bước 1: Bấm chuột phải vào thư mục values của Project/ chọn New/Android XML File:

13_lv_3Bước 2: Màn hình New Android XML hiển thị lên, bạn chọn thông số giống như hình bên dưới, đặt tên tập tin là mystrings.xml rồi nhấn nút Finish:

13_lv_4Xem kết quả khi bấm nút Finish và quan sát cho nhận xét:

13_lv_5Chú ý là ta cũng có thể thêm dữ liệu vào tập tin strings.xml, nhưng đây là ý đồ của Tôi, Tôi muốn hướng dẫn các bạn cách tạo 1 tập tin XML mới và thêm dữ liệu vào tập tin mới này luôn.

Bước 3: chọn tab Resource ở hình trên:

13_lv_6Bước 4: Bấm nút “Add…” ở màn hình trên để thêm String-Array:

13_lv_7

Ở màn hình trên bạn chọn String Array rồi nhấn OK:

Bước 5: Đặt tên cho String Array, sau khi nhấn OK thì màn hình bên dưới hiển thị ra, bạn đặt tên String Array này là myarray rồi nhấn ctrl+s để lưu:

13_lv_8

Bước 6: Thêm các phần tử vào String Array, tiếp tục bấm nút Add ở màn hình bên trên:

13_lv_9-Sau khi nhấn OK thì nó sẽ cho phép bạn nhập giá trị cho phần tử.

– Bạn cứ lặp liên tục thao tác ở bước 6 này, thêm bao nhiêu phần tử thì click từng đó lần Add, ở đây là Tôi thêm 3 phần tử, bạn xem hình:

13_lv_10

– Xem nội dung XML:

[code language=”xml”]

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="myarray">
<item >Trần Văn Tèo</item>
<item >Nguyễn Thị Tẹt</item>
<item >Hồ Văn Hiến</item>
</string-array>
</resources>

[/code]

– Như vậy bạn đã biết cách tao 1 tập tin XML và biết cách tạo String Array cũng như tạo các phần tử nằm bên trong nó, Bây giờ trong Coding ta sẽ dựa vào myarray để đọc toàn bộ dữ liệu từ XML ra. Bạn cũng chú ý là myarray khi bạn tạo ra ở trên thì nó cũng được tạo ra trong gen:

13_lv_11

– Như bạn thấy đó, trong coding ta sẽ dựa vào đây để lấy ra: R.array.myarray.

* Mở MainActivity.java lên:

– Như Tôi đã nói là mọi thứ nó y xì như trường hợp số 1, dó đó trong trường hợp này Tôi chỉ viết dòng lệnh đọc dữ liệu từ XML đổ về một Mảng (thay vì trường hợp 1 Tôi hardcode mấy phần tử khi khai báo mảng), còn các phần khác bạn tự làm giống trường hợp 1:

final String arr[]=getResources().getStringArray(R.array.myarray);

Tức là bạn thay thế dòng lệnh thứ 17 trong trường hợp 1 của MainActivity.java bằng dòng lệnh trên.

Thực thi ứng dụng bạn sẽ được kết quả như hình bên dưới:

13_lv_13

– Tôi nghĩ tới đây bạn đã thật sự hiểu trường hợp 2.

– Bạn có thể tải toàn bộ coding mẫu ở đây: http://www.mediafire.com/?168jsno9iq85qsc

3) Trường hợp 3: Sử dụng   ArrayList  và Listview control:

– Trường hợp này Tôi muốn hướng dẫn các bạn cách sử dụng ArrayList để lưu trữ dữ liệu và đổ lên ListView như thế nào, bạn xem giao diện của chương trình:

13_lv_12– Mô tả:

+ Nhập dữ liệu và nhấn nút “Nhập” thì sẽ đưa vào ArrayList và hiển thị lên ListView

+ Nhấn vào phần tử nào thì hiển thị vị trí và giá trị của phần tử đó lên TextView

+ Nhấn thật lâu (long click ) vào phần tử nào đó trên ListView thì sẽ xóa phần tử đó.

* Tạo Android Project tên: Vidu_ListView_ArrayList,

Xem Layout XML của ứng dụng (activity_main.xml):

[code language=”xml”]

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" >
<EditText android:id="@+id/txtTen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:inputType="text" android:layout_toRightOf="@+id/textView1" android:ems="10" />
<TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBaseline="@+id/txtTen" android:layout_alignBottom="@+id/txtTen" android:layout_alignParentLeft="true" android:background="#deb887" android:text="Nhập tên:" />
<Button android:id="@+id/btnNhap" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@+id/txtTen" android:layout_below="@+id/txtTen" android:layout_toRightOf="@+id/textView1" android:textAlignment="center" android:text="Nhập" />

<TextView android:id="@+id/txtselection" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/btnNhap" android:background="#007380" />

<ListView android:id="@+id/lvperson" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/txtselection" android:background="#cccccc" >
</ListView>
</RelativeLayout>

[/code]

Xem MainActivity.java:

[code language=”java”]

package tranduythanh.com;

import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends Activity {
EditText txtten;
TextView txtchon;
Button btn;
ListView lv;
ArrayList<String>arrList=null;
ArrayAdapter<String> adapter=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

txtten=(EditText) findViewById(R.id.txtTen);
txtchon=(TextView) findViewById(R.id.txtselection);

lv=(ListView) findViewById(R.id.lvperson);
//1. Tạo ArrayList object
arrList=new ArrayList<String>();
//2. Gán Data Source (ArrayList object) vào ArrayAdapter
adapter=new ArrayAdapter<String>
(this,
android.R.layout.simple_list_item_1,
arrList);
//3. gán Adapter vào ListView
lv.setAdapter(adapter);

btn=(Button) findViewById(R.id.btnNhap);
//4. Xử lý sự kiện nhấn nút Nhập
btn.setOnClickListener(new View.OnClickListener() {
public void onClick(View arg0) {
arrList.add(txtten.getText()+"");
adapter.notifyDataSetChanged();
}
});
//5. Xử lý sự kiện chọn một phần tử trong ListView
lv.setOnItemClickListener(new AdapterView
.OnItemClickListener() {
public void onItemClick(
AdapterView<?> arg0,View arg1,
int arg2,long arg3) {

txtchon.setText("position : "+ arg2+
"; value ="+arrList.get(arg2));
}
});
//6. xử lý sự kiện Long click
lv.setOnItemLongClickListener(new AdapterView
.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
arrList.remove(arg2);//xóa phần tử thứ arg2
adapter.notifyDataSetChanged();
return false;
}
});
}
}

[/code]

Tôi giải thích thêm về coding:
ArrayList bạn đã được học trong môn Java 1 rồi. Ở đây Tôi nói hàm adapter.notifyDataSetChanged(); Bạn chú ý là ArrayList được gán vào adapter nên mọi sự thay đổi trong ArrayList thì adapter đều nhận biết được. Khi có sự thay đổi trong ArrayList bạn chỉ cần gọi notifyDataSetChanged thì ListView sẽ được cập nhật (bởi vì Adapter được gắn vào ListView).

– Sự kiện setOnItemLongClickListener, được gắn cho ListView Item, khi nhấn lâu từ 2.5 tới 3 giây thì sự kiện này sẽ sảy ra. Tương tự như setOnItemClickListener , đối số có tên arg2 được dùng để xác định được vị trí của phần tử nằm trong ArrayList.

– Bạn có thể vào đây để tải coding mẫu: http://www.mediafire.com/?64k77e8yiazar8i

4) Trường hợp 4: Sử dụng ArrayList và ListView nhưng từng phần tử trong ArrayList là các Object bất kỳ:

– Tôi có một ví dụ về hiển thị danh sách nhân viên theo mô hình sau:

13_lv_14– Có 2 loại nhân viên : Nhân viên chính thức (EmployeeFullTime ) và nhân viên thời vụ (EmployeePartime).

– Mỗi nhân viên sẽ có cách tính lương khác nhau (tên phương thức tính lương giống nhau)

– Mỗi nhân viên có phương thức toString để xuất thông tin, Nội dung xuất khác nhau. Thêm FullTime đằng sau Id và Name đối với nhân viên chính thức. Thêm Partime đằng sau Id và Name đối với nhân viên thời vụ.

– Xem giao diện chương trình:

13_lv_15-Tạo một Android Project tên: Vidu_ListView_ArrayList_Object, cấu trúc như bên dưới:

13_lv_16

– Layout XML (activity_main.xml):

[code language=”xml”]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/LinearLayout1" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity" >

<TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#008000" android:gravity="center" android:text="Quản lý nhân viên" android:textColor="#FFFFFF" android:textSize="20sp" />

<TableLayout android:layout_width="match_parent" android:stretchColumns="*" android:layout_height="wrap_content" >

<TableRow android:id="@+id/tableRow1" 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="Mã NV:" />

<EditText android:id="@+id/editMa" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_span="2" android:ems="10" >

<requestFocus />
</EditText>

</TableRow>

<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="Tên NV:" />

<EditText android:id="@+id/editTen" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_span="2" android:ems="10" />

</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="Loại NV:" />

<RadioGroup android:id="@+id/radiogroud1" android:orientation="horizontal" >

<RadioButton android:id="@+id/radChinhthuc" android:layout_width="wrap_content" android:layout_height="wrap_content" android:checked="true" android:text="Chính thức" />

<RadioButton android:id="@+id/radThoivu" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Thời vụ" />
</RadioGroup>

</TableRow>

<TableRow android:id="@+id/tableRow4" 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:text="Nhập NV" />

</TableRow>
</TableLayout>

<TextView android:id="@+id/textView5" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#008000" />

<ListView android:id="@+id/lvnhanvien" android:layout_width="match_parent" android:layout_height="wrap_content" >
</ListView>

</LinearLayout>

[/code]

– Xem nội dung từng class:

– Abstract class Employee:

[code language=”java”]

package tranduythanh.com;

public abstract class Employee {
private String id;
private String name;

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 abstract double TinhLuong();
@Override
public String toString() {
// TODO Auto-generated method stub
return this.id+" – "+this.name;
}
}

[/code]

– class EmployeeFullTime:

[code language=”java”]

package tranduythanh.com;

public class EmployeeFullTime extends Employee {

@Override
public double TinhLuong() {
return 500;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString() +" –>FullTime="+TinhLuong();
}
}

[/code]

– Class EmployeePartTime:

[code language=”java”]

package tranduythanh.com;

public class EmployeePartTime extends Employee {

@Override
public double TinhLuong() {
// TODO Auto-generated method stub
return 150;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString() +" –>PartTime="+TinhLuong();
}
}

[/code]

– Bạn thấy là 2 class dẫn xuất từ Employee Tôi làm đơn giản là cách tính lương khác nhau. Đối với FullTime thì lương 500, Partime lương 150. và hàm Xuất toString() cũng khác nhau 1 xí.

– Ở đây ta sẽ áp dụng tính đa hình thông qua thừa kế, chỉ cần dùng một biến có kiểu Employee, nhưng nó có thể hiểu FullTime hoặc Partime và xuất ra thông tin đúng như mình mong đợi.

– Xem class MainActivity.java:

[code language=”java”]

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.RadioGroup;

public class MainActivity extends Activity {

EditText editId,editName;
Button btnNhap;
RadioGroup radgroup;
ListView lvNhanvien;
ArrayList<Employee>arrEmployee=new ArrayList<Employee>();
ArrayAdapter<Employee>adapter=null;
//Khai báo 1 employee object
Employee employee=null;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editId=(EditText) findViewById(R.id.editMa);
editName=(EditText) findViewById(R.id.editTen);
btnNhap=(Button) findViewById(R.id.btnnhap);
radgroup=(RadioGroup) findViewById(R.id.radiogroud1);
lvNhanvien=(ListView) findViewById(R.id.lvnhanvien);
//đưa Data Source là các employee vào Adapter
adapter=new ArrayAdapter<Employee>(this,
android.R.layout.simple_list_item_1,
arrEmployee);
//đưa adapter vào ListView
lvNhanvien.setAdapter(adapter);

btnNhap.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
processNhap();
}
});
}
//Xử lý sự kiện nhập
public void processNhap()
{
//Lấy ra đúng id của Radio Button được checked
int radId=radgroup.getCheckedRadioButtonId();
String id=editId.getText()+"";
String name=editName.getText()+"";
if(radId==R.id.radChinhthuc)
{
//tạo instance là FullTime
employee=new EmployeeFullTime();
}
else
{
//Tạo instance là Partime
employee=new EmployeePartTime();
}
//FullTime hay Partime thì cũng là Employee
//nên có các hàm này là hiển nhiên
employee.setId(id);
employee.setName(name);
//Đưa employee vào ArrayList
arrEmployee.add(employee);
//Cập nhập giao diện
adapter.notifyDataSetChanged();
}
}

[/code]

– Chương trình sẽ tự động hiển thị đúng loại Employee mà ta chọn lựa trên giao diện, ở đây bạn lại được ôn tập thêm về tính đa hình trong java. Ứng với mỗi loại Employee nó sẽ tự động gọi hàm toString của loại đó.

Ví dụ: Nếu Employee đó là FullTime thì nó gọi toString của FullTime và ngược lại với PartTime cũng vậy nó sẽ lấy toString của PartTime.

– Đến đây bạn đã hiểu tương đối sâu về ListView, bạn có thể tải coding mẫu ở đây: http://www.mediafire.com/?o1we6e0mw8cpbba

5)Trường hợp 5: Sử dụng ListView nhưng dưới dạng ListActivity:

– Thay vì kế thừa từ Activity, ta sẽ cho kế thừa từ ListActivity.

– Và dĩ nhiên cách đặt Id cho ListView cũng có sự khác biệt.

– Bạn xem giao diện bên dưới:

13_lv_17– Xem cách làm XML layout (activity_main.xml):

[code language=”xml”]
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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="#008000" android:textColor="#FFFFFF" android:textSize="20sp" />

<ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" >
</ListView>

<TextView android:id="@android:id/empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Không có gì cả" />

</LinearLayout>

[/code]

– Bạn nhìn vào dòng lệnh thứ 18:

android:id=”@android:id/list“, bạn viết y xì như thế nàyBởi vì nó là id được định nghĩa sẵn bên trong Android.

– Tiếp tục nhìn vào dòng lệnh 24:

android:id=”@android:id/empty , cũng là có sẵn của Android. Nó có tác dụng tự động thông báo khi ListView của bạn không có bất kỳ một phần tử nào cả.

– Xem class MainActivity.java:

[code language=”java”]
package tranduythanh.com;

import android.os.Bundle;
import android.app.ListActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends ListActivity {

TextView selection;
String arr[]={"Intel","SamSung",
"Nokia","Simen","AMD",
"KIC","ECD"};
ArrayAdapter<String >adapter=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Thiết lập Data Source cho Adapter
adapter=new ArrayAdapter<String>
(this,
android.R.layout.simple_list_item_1,
arr);
//Gán Adapter vào ListView
//Nhớ là phải đặt id cho ListView theo đúng quy tắc
setListAdapter(adapter);

selection=(TextView) findViewById(R.id.selection);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// TODO Auto-generated method stub
super.onListItemClick(l, v, position, id);
String txt="postion = "+position +"; value ="+arr[position];
selection.setText(txt);
}
}
[/code]

– Bạn nhìn vào dòng lệnh số 10: bạn thấy đấy, Tôi cho kế thừa từ ListActivity chứ không phải Activity. (Android đã viết class ListActivity kế thừa từ Activity rồi). Tức là ListActivity cũng chính là Activity.

– Bạn nhìn vào dòng lệnh số 28:

setListAdapter(adapter);

Ở đây ta hoàn toàn không “Lôi” control ListView ra. Mà ta chỉ cần gọi hàm setListAdapter thì ListView cũng tự động cập nhập dữ liệu. Bạn phải làm chính xác 2 nơi thì mới được như vậy:

1. Kết thừa từ ListActivity,

2. đặt id cho ListView theo đúng quy tắc android:id=”@android:id/list”

– Bạn load coding đầy đủ ở đây: http://www.mediafire.com/?mjxgs1yv0mvujuz

*** Như vậy bạn đã thực hành xong 5 trường hợp mà Tôi đã nêu. Tôi hi vọng các bạn hãy làm lại nhiều lần để có thể hiểu sâu hơn về nó.

Bài tập kế tiếp bạn sẽ được thực hành về cách Custom layout lại ListView theo ý thích của bạn.

Chúc bạn thành công.

Bài tập 12: Ví dụ tổng hợp TextView, EditText, CheckBox, Button và ImageButton trong Android

[polldaddy poll=9764234]

Trong bài tập 10 và bài tập 11 bạn đã làm quen được với các control này. Trong bài tập 12 Tôi sẽ làm một ví dụ tổng hợp + kết hợp với ArrayList để bạn củng cố thêm kiến thức về các control đã học.

– Viết chương trình thanh toán tiền bán sách (bạn đừng quan tâm là chương trình này nó có được ứng dụng thực tế hay không, hãy quan tâm cách viết code để hiểu thêm về các control):

12_th_0

–  Mô tả yêu cầu:

  • Khi bấm nút Tính Thành Tiền (Tính TT) chương trình sẽ tính thành tiền biết rằng mỗi cuốn sách có đơn giá là 20000, nếu là khách hàng VIP thì giảm 10%
  • Khi bấm nút Tiếp, chương trình sẽ lưu thông tin hóa đơn vừa tính Thành Tiền vào danh sách, đồng thời xóa trắng dữ liệu trong hóa đơn và cho focus tới EditText Tên khách hàng
  • Khi bấm nút Thống kê, chương trình sẽ hiển thị thông tin vào mục Thông tin thống kê: tổng số KH, tổng số KH VIP và tổng doanh thu
  • Khi bấm vào nút thoát (dùng ImageButton): hiển thị AlertDialog hỏi xem người sử dụng có chắc chắn muốn thoát hay không?
  • Dùng ScrollView để chương trình có thể làm việc tốt hơn khi sử dụng các thiết bị có màn hình nhỏ.

– Bạn tham khảo Outline để cho dễ thiết kế:

12_th_1

– Vì có thể bạn sẽ “bực bội” khi nhìn thấy Outline ở trên vì vậy Tôi cung cấp luôn XML của Outline này, bạn chỉ việc copy paste vào nếu “làm biếng”:

[code language=”xml”]
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ScrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#008080"
android:gravity="center"
android:text="Chương trình tính tiền bán sách online"
android:textColor="#FFFFFF"
android:textSize="15sp"
android:textStyle="bold" />

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:text="Thông tin hóa đơn:"
android:textSize="15sp" />

<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1" >

<TableRow
android:id="@+id/tableRow1"
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="Tên Khách Hàng:" />

<EditText
android:id="@+id/edittenkh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:text="Đoàn Ái Nương" >

<requestFocus />
</EditText>
</TableRow>

<TableRow
android:id="@+id/tableRow2"
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="Số lượng sách:" />

<EditText
android:id="@+id/editsoluongsach"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:text="113" />
</TableRow>

<TableRow
android:id="@+id/tableRow3"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<CheckBox
android:id="@+id/chklavip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_column="1"
android:checked="true"
android:text="Khách hàng là VIP" />
</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="Thành tiền:" />

<TextView
android:id="@+id/txtthanhtien"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#C0C0C0"
android:gravity="center"
android:text="2034000"
android:textColor="#008000"
android:textSize="20sp" />
</TableRow>

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<Button
android:id="@+id/btntinhtt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Tính TT" />

<Button
android:id="@+id/btntiep"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Tiếp" />

<Button
android:id="@+id/btnthongke"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Thống kê" />
</LinearLayout>
</TableLayout>

<TextView
android:id="@+id/TextView01"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#FFFF00"
android:text="Thông tin thống kê:"
android:textSize="15sp" />

<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:stretchColumns="1" >

<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="Tổng số KH:" />

<EditText
android:id="@+id/edittongsokh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:text="3" />
</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="Tổng số KH là VIP:" />

<EditText
android:id="@+id/edittongsokhlavip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="number"
android:text="1" />
</TableRow>

<TableRow
android:id="@+id/tableRow7"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tổng doanh thu:" />

<EditText
android:id="@+id/edittongdt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="numberDecimal"
android:text="2184000" />
</TableRow>
</TableLayout>

<TextView
android:id="@+id/textView9"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#008080" />

<ImageButton
android:id="@+id/imgbtnthoat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:src="@drawable/exit" />
</LinearLayout>

</ScrollView>

[/code]

Bạn cần chú ý là ở cuối XML có ImageButton, nhìn vào thuộc tính android:src=“@drawable/exit” . Ở đây bạn tạo một hình có tên exit.png rồi kéo vào thư mục drawable (bạn có thể tự tạo 1 thư mục mới tên là drawable vào trong ứng dụng của bạn).

– Bạn xem cấu trúc tập tin src của ứng dụng này:

12_th_2– Ở trên có MainActivity.java (là màn hình chính của ứng dụng mà bạn thấy ở phần giới thiệu)

– class KhachHang dùng để lưu thông tin của khách hàng: Tên khách hàng, số lượng mua, thành tiền, là VIP hay không

– class DanhSachKhachHang dùng để lưu trữ các khách hàng mua sách, đồng thời cung cấp một số hàm như: tính tổng tiền, tính tổng số khách hàng, tính tổng số khách hàng VIP….

Dưới đây là chi tiết cho từng class:

class KhachHang:

[code language=”java”]
package tranduythanh.com;

public class KhachHang {

private String tenKh;

private int slmua;

private boolean isVip;

public static final int GIA=20000;

public KhachHang()

{

}

public KhachHang(String tenKh,int slmua,boolean isVip)

{

this.tenKh=tenKh;

this.slmua=slmua;

this.isVip=isVip;

}

public String getTenKh() {

return tenKh;

}

public void setTenKh(String tenKh) {

this.tenKh = tenKh;

}

public int getSlmua() {

return slmua;

}

public void setSlmua(int slmua) {

this.slmua = slmua;

}

public boolean isVip() {

return isVip;

}

public void setVip(boolean isVip) {

this.isVip = isVip;

}

public double tinhThanhTien()

{

return (!isVip?slmua*GIA:slmua*GIA*0.9);

}

}
[/code]

Class DanhSachKhachHang:

[code language=”java”]
package tranduythanh.com;

import java.util.ArrayList;

public class DanhSachKhachHang {

ArrayList<KhachHang>listKH=new ArrayList<KhachHang>();

public void addKhachHang(KhachHang kh)

{

listKH.add(kh);

}

public double tongDoanhThu()

{

double tien=0.0;

for(KhachHang kh:listKH)

{

tien+=kh.tinhThanhTien();

}

return tien;

}

public int tongKhachHang()

{

return listKH.size();

}

public int tongKhachHangVip()

{

int s=0;

for(KhachHang kh:listKH)

{

if(kh.isVip())

s++;

}

return s;

}

}
[/code]

class MainActivity:

– Dùng để triệu gọi 2 class trên và thực thi các nghiệp vụ:

[code language=”java”]
package tranduythanh.com;

import android.os.Bundle;

import android.app.Activity;

import android.app.AlertDialog;

import android.content.DialogInterface;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.EditText;

import android.widget.ImageButton;

import android.widget.TextView;

public class MainActivity extends Activity {

Button btnTT,btnTiep,btnTK;

ImageButton btnThoat;

EditText editTen,editSl,editTongKh,editTongKhVip,ediTongTT;

TextView txtTT;

CheckBox chkVip;

DanhSachKhachHang danhsach=new DanhSachKhachHang();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

getControls();

addEvents();

}

private void getControls()

{

btnTT=(Button) findViewById(R.id.btntinhtt);

btnTiep=(Button) findViewById(R.id.btntiep);

btnTK=(Button) findViewById(R.id.btnthongke);

btnThoat=(ImageButton) findViewById(R.id.imgbtnthoat);

editTen=(EditText) findViewById(R.id.edittenkh);

editSl=(EditText) findViewById(R.id.editsoluongsach);

editTongKh=(EditText) findViewById(R.id.edittongsokh);

editTongKhVip=(EditText) findViewById(R.id.edittongsokhlavip);

ediTongTT=(EditText) findViewById(R.id.edittongdt);

txtTT=(TextView) findViewById(R.id.txtthanhtien);

chkVip =(CheckBox) findViewById(R.id.chklavip);

}

private void addEvents()

{

btnTT.setOnClickListener(new ProcessMyEvent());

btnTiep.setOnClickListener(new ProcessMyEvent());

btnTK.setOnClickListener(new ProcessMyEvent());

btnThoat.setOnClickListener(new ProcessMyEvent());

}

private void doTinhTien()

{

KhachHang kh=new KhachHang();

kh.setTenKh(editTen.getText()+”");

kh.setSlmua(Integer.parseInt(editSl.getText()+”"));

kh.setVip(chkVip.isChecked());

txtTT.setText(kh.tinhThanhTien()+”");

danhsach.addKhachHang(kh);

}

private void doTiep()

{

editTen.setText(“”);

editSl.setText(“”);

txtTT.setText(“”);

editTen.requestFocus();

}

private void doThongKe()

{

editTongKh.setText(danhsach.tongKhachHang()+”");

editTongKhVip.setText(danhsach.tongKhachHangVip()+”");

ediTongTT.setText(danhsach.tongDoanhThu()+”");

}

private void doThoat()

{

AlertDialog.Builder builder=new AlertDialog.Builder(this);

builder.setTitle(“hỏi thoát chương trình”);

builder.setMessage(“Muốn thoát chương trình này hả?”);

builder.setNegativeButton(“Không”, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

dialog.cancel();

}

});

builder.setPositiveButton(“Có”, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

finish();

}

});

builder.create().show();

}

private class ProcessMyEvent implements OnClickListener

{

@Override

public void onClick(View arg0) {

switch(arg0.getId())

{

case R.id.btntinhtt:

doTinhTien();

break;

case R.id.btntiep:

doTiep();

break;

case R.id.btnthongke:

doThongKe();

break;

case R.id.imgbtnthoat:

doThoat();

break;

}

}

}

}
[/code]

– Trong MainActivity Tôi cố tình tách các nghiệp vụ ra thành các hàm riêng biệt như vậy để bạn dễ dàng xử lý. Chúng ta nên tập viết như vậy để Coding được sạch sẽ, khi có lỗi sảy ra cũng giúp các bạn dễ Fixed bug, sai hàm nào thì sửa hàm đó mà nó không bị ảnh hưởng tới các nghiệp vụ khác.

– Bạn có thể load đầy đủ coding mẫu  trong link này: http://www.mediafire.com/?lgq5g2l28xb222c

– Bạn phải hiểu cách làm bài tập này để ứng dụng cho các phần sau.

– Hãy thực hành bài này nhiều lần cho tới khi thực sự hiểu logic của nó.

– Bài tập tiếp theo bạn sẽ được học về các control nâng cao trong Android, và ta sẽ thực hành thật kỹ từng control cụ thể, đầu tiên là ListView (control rất thường xuyên được sử dụng trong một chương trình Android nào đó).

– Chúc các bạn thành công

Bài tập 11: Sử dụng Checkbox và RadioButton trong Android

[polldaddy poll=9764234]

bài tập 10 bạn đã biết cách sử dụng TextView, EditText và Button. Trong bài tập này Tôi sẽ hướng dẫn các bạn cách sử dụng CheckBox và RadioButton. 2 Control này cũng rất thường xuyên được sử dụng trong các chương trình.

– CheckBox và RadioButton đều sử dụng chung 2 phương thức :

1) phương thức setChecked, dùng để thiết lập checked. Nếu ta gọi setChecked(true)  tức là cho phép control được checked, còn gọi setChecked(false) thì control sẽ bị unchecked.

2) phương thức isChecked, kiểm tra xem control có được checked hay không. Nếu có checked thì trả về true ngược lại trả về false

– Checkbox cho phép ta checked nhiều đối tượng,  còn RadioButton thì tại một thời điểm nó chỉ cho ta checked 1 đối tượng trong cùng một group mà thôi.

– Nếu bạn muốn người sử dụng có thể chọn nhiều lựa chọn thì bạn nên sử dụng Checkbox, ví dụ xem hình bên dưới:

11_chk_rad_0– Ta có thể thiết lập cho Checkbox bất kỳ được checked mặc định trong XML:

11_chk_rad_2-Trong coding để kiểm tra xem Checkbox đó có được checked hay không thì làm như sau:

11_chk_rad_4

– Nếu bạn muốn người sử dụng chỉ được chọn 1 lựa chọn trong nhiều chọn lựa bạn đưa ra thì nên sử dụng RadioButton, ví dụ xem hình bên dưới:

11_chk_rad_1– Tương tự như Checkbox, ta cũng có thể thiết lập checked cho RadioButton bất kỳ trong XML:

11_chk_rad_3– Nhìn vào hình trên bạn thấy là ta phải sử dụng RadioGroup để gom nhóm các RadioButton lại cùng một nhóm nào đó, những RadioButton mà cùng một nhóm thì tại 1 thời điểm chỉ có 1 RadioButton được checked mà thôi. Trong một màn hình ta có thể tạo nhiều nhóm RadioGroup khác nhau.

– Tôi cung cấp 2 cách xử lý RadionButton nào được checked như sau:

Cách 1: Dựa vào RadioGroup để biết chính xác Id của RadioButton nào được checked. Dựa vào Id này ta sẽ xử lý đúng nghiệp vụ:

11_chk_rad_5– Như hình trên, bạn thấy hàm getCheckedRadioButtonId() : hàm này trả về Id của RadioButton nằm trong RadioGroup 1 được checked. Dựa vào Id này bạn so sánh để biết được trên giao diện người sử dụng đang checked lựa chọn nào.

Cách 2: Kiểm tra trực tiếp RadioButton đó có được checked hay không?

11_chk_rad_6

Cả 2 cách trên đều có cùng chung một mục đích chỉ là kỹ thuật xử lý khác nhau, tương tự để xóa bỏ checked trong group, ta dùng lệnh:

group.clearChecked();

với group là đối tượng RadioGroup.

– Bây giờ Tôi sẽ demo một ví dụ kết hợp giữa RadioButton và CheckBox để bạn hiểu sâu hơn về 2 control này:

11_chk_rad_7– Mô tả:

–          Tên người không được để trống và phải có ít nhất 3 ký tự

–          Chứng minh nhân dân chỉ được nhập kiểu số và phải có đúng 9 chữ số

–          Bằng cấp mặc định sẽ chọn là Đại học

–          Sở thích phải chọn ít nhất 1 chọn lựa

–          Thông tin bổ sung có thể để trống

–          Khi bấm gửi thông tin, chương trình sẽ hiển thị toàn bộ thông tin cá nhân cho người sử dụng biết (dùng Alert Dialog):

11_chk_rad_8– Bạn xem Outline của MainActivity để dễ thiết kế:

11_chk_rad_9Bạn xem coding trong MainActivity:

package tranduythanh.com;

import android.os.Bundle;

import android.app.Activity;

import android.app.AlertDialog;

import android.content.DialogInterface;

import android.view.Menu;

import android.view.View;

import android.widget.Button;

import android.widget.CheckBox;

import android.widget.EditText;

import android.widget.RadioButton;

import android.widget.RadioGroup;

import android.widget.Toast;

public class MainActivity extends Activity {

EditText editTen,editCMND,editBosung;

CheckBox chkdocbao,chkdocsach,chkdoccode;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

editTen=(EditText) findViewById(R.id.editHoten);

editCMND=(EditText) findViewById(R.id.editCMND);

editBosung=(EditText) findViewById(R.id.editBosung);

chkdocbao=(CheckBox) findViewById(R.id.chkdocbao);

chkdoccode=(CheckBox) findViewById(R.id.chkdoccoding);

chkdocsach=(CheckBox) findViewById(R.id.chkdocsach);

Button btn=(Button) findViewById(R.id.btnguitt);

btn.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View arg0) {

// TODO Auto-generated method stub

doShowInformation();

}

});

}

public void doShowInformation()

{

//Kiểm tra tên hợp lệ

String ten=editTen.getText()+””;

ten=ten.trim();

if(ten.length()<3)

{

editTen.requestFocus();

editTen.selectAll();

Toast.makeText(this, “Tên phải >= 3 ký tự”, Toast.LENGTH_LONG).show();

return;

}

//kiểm tra CMND hợp lệ

String cmnd=editCMND.getText()+””;

cmnd=cmnd.trim();

if(cmnd.length()!=9)

{

editCMND.requestFocus();

editCMND.selectAll();

Toast.makeText(this, “CMND phải đúng 9 ký tự”, Toast.LENGTH_LONG).show();

return;

}

//Kiểm tra bằng cấp

String bang=””;

RadioGroup group=(RadioGroup) findViewById(R.id.radioGroup1);

int id=group.getCheckedRadioButtonId();

if(id==-1)

{

Toast.makeText(this, “Phải chọn bằng cấp”, Toast.LENGTH_LONG).show();

return;

}

RadioButton rad=(RadioButton) findViewById(id);

bang=rad.getText()+””;

//Kiểm tra sở thích

String sothich=””;

if(chkdocbao.isChecked())

sothich+=chkdocbao.getText()+”\n”;

if(chkdocsach.isChecked())

sothich+=chkdocsach.getText()+”\n”;

if(chkdoccode.isChecked())

sothich+=chkdoccode.getText()+”\n”;

String bosung=editBosung.getText()+””;

AlertDialog.Builder builder=new AlertDialog.Builder(this);

builder.setTitle(“Thông tin cá nhân”);

builder.setPositiveButton(“Đóng”, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which) {

// TODO Auto-generated method stub

dialog.cancel();

}

});

//tạo nội dung

String msg=ten+”\n”;

msg+= cmnd+”\n”;

msg+=bang+”\n”;

msg+=sothich;

msg+=”—————————–\n”;

msg+=”Thông tin bổ sung:\n”;

msg+=bosung+ “\n”;

msg+=”—————————–“;

builder.setMessage(msg);//thiết lập nội dung

builder.create().show();//hiển thị Dialog

}

@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;

}

}

chú ý các cách dùng sự kiện trong  đoạn code ở trên.

Bạn có thể tải coding mẫu đầy đủ ở đây: http://www.mediafire.com/?wqih1ln20rilsv8

Tới đây bạn đã hiểu được phầnn nào CheckBox và RadioButton

– Bài tập kế tiếp Tôi sẽ làm một ví dụ tổng hợp về EditText, CheckBox, Button … cùng ArrayList để bạn hiểu thêm về các control cơ bản này.

– Chúc các bạn thành công

Bài tập 10: Sử dụng TextView, EditText và Button trong Android

Nếu bạn nào muốn rèn luyện thêm lập trình Java, lập trình Android, lập trình Webservice với tổng thời lượng học >80 giờ thì có thể đăng ký học theo các link sau:

1) Lập trình java trong 4 tuần – 19 giờ(chỉ dành cho những ai CHƯA BIẾT GÌ VỀ LẬP TRÌNH hoặc đã biết lơ mơ về Java, lý thuyết và các bài tập phong phú tạo nền tảng lập trình Android và các hướng khác liên quan tới Java):
https://kyna.vn/lap-trinh-java-trong-4-tuan/325931
2) Lập trình Android cơ bản (>24 giờ học) – toàn bộ kiến thức về Android cơ bản:
https://kyna.vn/lap-trinh-android-co-ban/325931
3) Lập trình Android nâng cao (23 giờ học) – toàn bộ kiến thức về Android nâng cao:
https://kyna.vn/lap-trinh-android-nang-cao/325931
4) Lập trình Webservice cho Di Động – 14 giờ (dành cho những ai ĐÃ BIẾT ANDROID), những ai chưa biết Android tuyệt đối không đăng ký, khóa học hướng dẫn tỉ mỉ từ A->Z để có thể xây dựng được một phần mềm hoàn chỉnh tương tác client-server:
https://kyna.vn/lap-trinh-webservice-cho-di-dong/325931

[polldaddy poll=9764234]

– TextView, EditText, Button là 3 control cơ bản nhất của Android. Trong các bài tập trước bạn đã được làm quen với 3 control này rồi. Bài tập này Tôi sẽ làm lại mục đích giúp các bạn ôn tập lại đồng thời giúp hiểu thêm được một số thuộc tính mới của nó (trong Android người ta thường gọi một số các control là  Form Widgets).

1) TextView:

– Bạn chỉ muốn hiển thị thông tin mà không cho phép người dùng chỉnh sửa thì nên sử dụng control này.

– TextView tương tự như  JLabel bên Java, và như Label bên C#

– Dưới này Tôi chụp một số thuộc tính của TextView mà chúng ta thường xuyên sử dụng nhất:

10_common_control_0

– Ta nên thiết lập id cho control để tiện bề xử lý.

– layout_width, layout_height nên thiết lập cho control(bắt buộc)

– Để thay đổi màu nền dùng background, thay đổi màu chữ dùng textColor…

– Để trợ giúp các bạn thay đổi màu nền và màu chữ của các control trong Android (dùng hex color), Tôi đã viết chương trình lấy màu theo mã hex color, các bạn có thể tải về tại : http://www.mediafire.com/?ujj2pyppdwemx69 . Giao diện như sau:

10_common_control_1

Chương trình này bạn có thể chọn button “…” để chọn custom color. Ứng với mỗi bảng màu khác nhau thì sẽ có mã Hex color khác nhau. Bạn copy mã này dán vào Ứng dụng Android của bạn thì sẽ có màu như ý muốn.

Thí dụ, ở màn hình trên Hex là “#3F8020“, bạn copy hex này và dán vào background của TextView (xem hình):

10_common_control_2-Như bên trên Tôi nói là nên đặt tên Id cho control, mục đích để xử lý một số công việc theo yêu cầu. Dựa vào Id ta sẽ lấy được control theo đúng Id này, xem code bên dưới để biết cách lấy control theo Id:

TextView txt1= (TextView) findViewById(R.id.textView1);

– Mọi control đều kế thừa từ View, và hàm findViewById cũng trả về 1 View theo đúng Id truyền vào, đó là lý do ta ép kiểu về cho đúng với TextView (cách làm nhanh: ngay dòng lệnh này nhấn tổ hợp phím Ctrl +1 là nó sẽ tự ép kiểu nhanh cho bạn)

– Để hiển thị thông tin lên control TextView ta dùng lệnh dưới đây:

txt1.setText(“Hello tèo”);

– Đẩy lấy thông tin bên trong control TextView ta dùng lệnh dưới đây:

String msg=txt1.getText().toString();

2) EditText:

– Control này kế thừa từ TextView và cho phép chỉnh sửa dữ liệu (dĩ nhiên bạn có thể cấm chỉnh sửa dữ liệu bằng coding hay trong xml)

– Để sử dụng EditText rất đơn giản, bạn chỉ việc kéo thả control này vào giao diện và tiến hành thiết lập một số thuộc tính:

10_common_control_3– Như hình bên trên thì bạn chỉ cần kéo loại EditText mà bạn cần (vùng số 1) rồi thả vào giao diện (vùng số 2)

– Bạn xem Tôi chụp một số thuộc tính của EditText trong hình dưới này:

10_common_control_4– Tương tự như TextView bạn cần thiết lập Id, các layout_width, layout_height

– Thuộc tính hint : để hiển thị thông tin gợi ý trong vùng nhập dữ liệu khi bạn chưa nhập bất kỳ dữ liệu nào vào, chỉ cần có dữ liệu là phần hint sẽ tự động mất đi.

textSize để thiết lập kích cỡ font chữ cho EditText

– Trong inputType bạn thấy Tôi kết hợp nhiều giá trị lại với nhau bằng cách dùng toán tử “|”, tức là EditText này sẽ có đầy đủ các đặc tính ở bên vế phải mà ta truyền vào, ví dụ:

+textAutoCorrect : Tự động sửa đúng chính tả, giả sử bạn nhập “teh” thì nó sẽ tự động sửa thành “the

+ vân vân… bạn tự tìm hiểu thêm trên mạng

– Ta cũng có thể dùng cửa sổ Properties để thiết lập thuộc tính cho dễ dàng hơn (click chuột vào EditText muốn đổi thuộc tính):

10_common_control_5-Màn hình trên cho phép ta thay đổi thuộc tính của control một cách dễ dàng.

– Tương tự như TextView, ta cũng phải lấy được control thông qua Id, thao tác với dữ liệu bên trong EditText:

+Lấy control theo Id:

EditText txtbox=(EditText) findViewById(R.id.editText1);

+Thiết lập giá trị cho EditText

txtBox.setText(“nhập bất cứ cái gì vào đây xem sao”)

+Lấy dữ liệu bên trong EditText:

String msg=txtBox.getText().toString()

3) Button:

– Dùng để thiết lập sự kiện khi người dùng chọn lựa.

– Cũng kế thừa từ TextView

– Có 2 sự kiện mà người sử dụng thường xuyên thao tác:

10_common_control_6– Bây giờ Tôi sẽ làm một ví dụ về cách sử dụng 3 control này (bạn có thể xem lại bài tập các kiểu lập trình sự kiện trong Android):

– Ví dụ đơn giản là tính cộng trừ nhân chia, giao diện như bên dưới (nhấn nút nào thì thực hiện phép toán cho nút đó):

10_common_control_8

– Bạn xem Layout để dễ thiết kế:

10_common_control_7– Coding mẫu:

package tranduythanh.com;

import android.os.Bundle;

import android.app.Activity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

public class MainActivity extends Activity {

Button btncong,btntru,btnnhan,btnchia;

EditText editsoa,editsob;

TextView txtkq;

OnClickListener myclick=new OnClickListener() {

@Override

public void onClick(View arg0) {

switch(arg0.getId())

{

case R.id.btncong:

String sa=editsoa.getText()+””;

String sb=editsob.getText().toString();

int a=Integer.parseInt(sa);

int b=Integer.parseInt(sb);

txtkq.setText(a+” + “+b +” = “+(a+b));

break;

case R.id.btntru:

break;

case R.id.btnnhan:

break;

case R.id.btnchia:

break;

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

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

btncong.setOnClickListener(myclick);

btntru.setOnClickListener(myclick);

btnnhan.setOnClickListener(myclick);

btnchia.setOnClickListener(myclick);

}

}

Bạn hãy trả lời cho Tôi: Hiện giờ đoạn code trên Tôi sử dụng loại Sự Kiện nào?

– Như vậy bạn đã hiểu được cách sử dụng TextView, EditText, Button.

– Các bài tập sau Tôi sẽ nói về CheckBox, RadioButton.

– Bạn phải hiểu thật tốt về 3 Control Tôi vừa nêu ở trên, nó rất là cơ bản và quan trọng, đa phần ứng dụng Android nào cũng sử dụng tối thiểu 3 Control này.

Chúc các bạn thành công.

Bài tập 9: Thực hành về Toast Notification và Alert Dialog

[polldaddy poll=9764234]

Vì trong tất cả các ứng dụng Tôi thấy rằng chúng ta hay sử dụng Toast và Alert Dialog để kiểm tra một điều gì đó, hay đơn giản chỉ là xuất thông báo. Vì vậy bài tập này Tôi sẽ hướng dẫn các bạn làm quen với Toast & Alert Dialog, sau đó các bạn sẽ được thực hành với các control cơ bản và nâng cao.

– Cả Toast và Alert Dialog khi hiển thị lên thì các tiến trình (hay các lệnh) khác  vẫn cứ tiếp tục làm việc.

1) Toast:

– Toast có thể được tạo và hiển thị trong Activity hoặc trong Servive.

– Không cho phép người sử dụng tương tác

– Khi hiển thị sau khoảng thời gian nào đó sẽ tự đóng lại

– Có 2 giá trị mặc định (ta nên sử dụng 2 giá trị này, không nên gõ con số cụ thể vào): hằng số Toast.LENGTH_SHORT hiển thị trong  2 giây, Toast.LENGTH_LONG hiển thị trong 3.5 giây.

Cách tạo Toast:

Toast toast=Toast.makeText(YourActivity.this, “Hiển thị gì thì ghi ở đây”,   Toast.LENGTH_SHORT);
toast.show();

– Khi nào bạn nên sử dụng Toast?

Theo Tôi thì tùy bạn, bạn có thể sử dụng trong trường hợp hiển thông báo trong các mục thiết lập thông số cấu hình, hay đơn giản chỉ là hiển thị lên để xem thông tin tạm thời nào đó (giống như để kiểm tra một vấn đề sảy ra chẳng hạn).

– Hình dưới đây cho bạn biết 1 Toast đang hiển thị:

9_dialog_02) Alert Dialog:

– Hiển thị và cho phép người dùng tương tác, ví dụ bạn nhìn hình Tôi chụp bên dưới, khi nhấn nút “Cancel”, chương trình sẽ hiển thị Alert Dialog hỏi xem có chắc chắn muốn xóa hay không? Bấm No thì không, bấm Yes thì tắt chương trình.

9_dialog_1– Cách tạo Alert Dialog:

AlertDialog.Builder b=new AlertDialog.Builder(YourActivity.this);
b.setTitle(“Question”);
b.setMessage(“Are you sure you want to exit?”);
b.setPositiveButton(“Yes”, new DialogInterface. OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which)
{
finish();
}});b.setNegativeButton(“No”, new DialogInterface.OnClickListener() {

@Override

public void onClick(DialogInterface dialog, int which)

{

dialog.cancel();

}

});

b.create().show();

Ý nghĩa của các hàm :

setTitle : thiết lập tiêu đề cho Dialog

setMessage: Thiết lập nội dung cho Dialog

setIcon : để thiết lập Icon

setPositiveButtonsetNegativeButton thiết lập hiển thị Nút chọn cho Dialog (ở đây bạn không quan tâm Nút chấp nhận hay Nút hủy nó thuộc PositiveButton hay NegativeButton vì đó là tùy thuộc bạn chọn. Chú ý là ở đối số thứ 2 của các hàm này sẽ là DialogInterface. OnClickListener chứ không phải View. OnClickListener

create() để tạo Dialog

show() để hiển thị Dialog.

Bài tập 8: Các kiểu lập trình sự kiện trong Android

[polldaddy poll=9764234]

Bài tập này Tôi sẽ trình bày 6 kiểu lập trình sự kiện trong Android. Tôi sẽ sử dụng một số Control căn bản để Demo, đặc biệt là Button dùng để tạo sự kiện.

  1. Onclick in XML
  2. Inline anonymous listener
  3. Activity is listener
  4. Listener in variable
  5. Explicit listener class
  6. View Subclassing

– Tôi sẽ lần lượt đưa ra 6 ví dụ khác nhau cho 6 kiểu lập trình sự kiện ở trên, các bạn hãy cố gắng theo dõi, nó rất quan trọng để làm các bài tập tiếp theo.

1. Onclick in XML:

– Ví dụ 1: Đơn giản chỉ là cộng 2 số, bạn thiết kế giao diện như bên dưới:

8_event_0– Khi nhấn vào nút “Tổng 2 số”, chương trình sẽ xuất kết quả như hình bên trên : 80+33= 113

– Bạn xem Layout Outline để dễ thiết kế (chú ý là bạn có thể bỏ LinearLayout1 đi):

8_event_1

– Chú ý là ta sử dụng Onclick in XML:

8_event_2– Trong đoạn lệnh ở trên thì ta sử dụng android:conClick=”btn_tong2so”, tức là ta đã gán một sự kiện click cho Button này, sự kiện này tên là btn_tong2so. Ta cần khai báo một hàm btn_tong2so ở trong Activity class như hình bên dưới:

8_event_3– Khi chạy ứng dụng bạn sẽ được kết quả như bên dưới:

8_event_4

2. Inline anonymous listener

– Ví dụ viết chương trình chuyển đổi năm dương lịch qua năm âm lịch như hình bên dưới:

8_event_5– Khi người sử dụng nhập vào EditText giá trị là 1 năm Dương Lịch bất kỳ nào đó rồi nhấn nút “Chuyển đổi”, chương trình sẽ chuyển năm dương lịch thành năm âm lịch. Trong ví dụ trên nếu người sử dụng nhập 2013 thì sẽ ra năm âm lịch là “Quý Tỵ”.

– Chú ý là ta tạo một anonymous listener, trước tiên bạn hãy xem Outline XML để cho dễ bề thiết kế:

8_event_6– Để chuyển từ năm dương lịch sang năm âm lịch bạn cần biết một số thông tin sau:

8_event_7

– Bây giờ ta tiến hành gán sự kiện cho nút “Chuyển đổi” (ở đây id Tôi để là button1), mở Activity class lên vào sửa lệnh như bên dưới:

8_event_8–  Bạn tự đưa lệnh vào Bước 1, Bước 2, bước 3 ở trên. Cách lấy dữ liệu nhập vào từ EditText đã hướng dẫn ở phần Onclick in XML, làm theo cái này để lấy được giá trị là năm dương lịch ra, sau đó lấy năm này xử lý theo bảng Can Chi như hướng dẫn thì Ta sẽ ra được năm Âm lịch tương ứng.

3. Activity is listener:

– Trong cách viết sự kiện này thì Activity sẽ implements interface có kiểu sự kiện (rất nhiều loại interface). Ở đây Tôi chỉ ví dụ trường hợp cho Button các trường hợp khác các bạn tự tìm hiểu và suy luận ra.

– Tôi sẽ có một bài ví dụ nhỏ sau: Hãy xây dựng ứng dụng tính Chỉ số khối cơ thể -chữ viết tắt BMI (Body Mass Index )- được dùng để đánh giá mức độ gầy hay béo của một người. Chỉ số này có thể giúp xác định một người bị bệnh béo phì hay bị bệnh suy dinh dưỡng.

+Cách tính như sau:

Gọi W là khối lượng của một người (tính bằng kg) và H là chiều cao của người đó (tính bằng m), chỉ số khối cơ thể được tính theo công thức:

8_event_9Phân loại để đánh giá như sau:

  • BMI < 18: người gầy
  • BMI = 18 – 24,9: người bình thường
  • BMI = 25 – 29,9: người béo phì độ I
  • BMI = 30 – 34,9: người béo phì độ II
  • BMI > 35: người béo phì độ III

Tôi sẽ thiết kế giao diện như hình bên dưới và cung cấp Outline, các bạn hãy thiết kế lại để nâng cao kinh nghiệm:

8_event_10-Bạn thấy đó: Thông số bên trên chính là của chính Tôi, Tên Tôi là Thanh, chiều cao 1.68 mét, cân nặng 58 kg. Khi Tôi chọn “Tính BMI” thì chương trình sẽ tính ra được BMI của Tôi là 20.5 và chẩn đoán là “Bình thường”, tức là Tôi có sức khỏe tốt, dáng người chuẩn (có thể là niềm ước ao của một số các bạn trong lớp).

– Để các bạn đỡ căng thẳng thì Tôi xin nói lý do vì sao Tôi lại viết phần mềm này làm ví dụ minh họa. Bởi vì bạn gái của Tôi luôn luôn chê Tôi gầy (hay gọi là Xí Quách gì đó). Tôi đã chứng mình là Tôi có dáng người chuẩn không cần chỉnh bằng cách viết phần mềm này (công thức theo chuẩn Quốc Tế nên nó là một bằng chứng không thể chối cãi). Tôi nghĩ các bạn cũng có thể dùng nó để chứng minh rằng mình không bị Béo Phì Cấp độ 3.

– Quay trở lại ví dụ ,Bạn xem Outline của giao diện này dưới đây (Tôi cố tình không cung cấp source XML nhằm mục đích kích thích các bạn tự tìm tòi):

8_event_11

– Đây là nội dung Coding trong Activity:

import java.text.DecimalFormat;

import android.os.Bundle;

import android.app.Activity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

public class MainActivity extends Activity

implements OnClickListener{

Button btnChandoan;

EditText editTen,editChieucao,

editCannang,editBMI,editChandoan;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btnChandoan=(Button) findViewById(R.id.btntinhBMI);

btnChandoan.setOnClickListener(this);

editTen=(EditText) findViewById(R.id.editten);

editChieucao=(EditText) findViewById(R.id.editchieucao);

editCannang=(EditText) findViewById(R.id.editcannang);

editBMI=(EditText) findViewById(R.id.editBMI);

editChandoan=(EditText) findViewById(R.id.editChanDoan);

}

@Override

public void onClick(View arg0) {

double H=Double.parseDouble(editChieucao.getText()+””);

double W=Double.parseDouble(editCannang.getText()+””);

double BMI=W/Math.pow(H, 2);

String chandoan=””;

if(BMI<18)

{

chandoan=”Bạn gầy”;

}

else if(BMI<=24.9)

{

chandoan=”Bạn bình thường”;

}

else if(BMI<=29.9)

{

chandoan=”Bạn béo phì độ 1″;

}

else if(BMI<=34.9)

{

chandoan=”Bạn béo phì độ 2″;

}

else

{

chandoan=”Bạn béo phì độ 3″;

}

DecimalFormat dcf=new DecimalFormat(“#.0”);

editBMI.setText(dcf.format(BMI));

editChandoan.setText(chandoan);

}

}

– a) Bạn quan sát Activity này sẽ implements interface OnClickListener

– b) Bản thân interface OnClickListener có mộ Abstract Method là onClick(View arg0) nên ta phải Override nó.

– c) Để Button có thể hiểu được sự kiện thì Ta phải gọi dòng lệnh: btnChandoan.setOnClickListener(this); bản thân Activity là một sự kiện nên ta dùng this để truyền vào hàm.

– d) Bạn quan sát thêm Tôi có sử dụng : DecimalFormat dcf=new DecimalFormat(“#.0“); Mục đích là Tôi định dạng 1 số lẻ thập phân, bạn muốn 2 số lẻ thập phần thì ghi “#.00” hay muốn 3 thì “#.000” …vân vân.

Bạn có thể load đầy đủ coding mẫu ở đây: http://www.mediafire.com/?71khpisxa3wmvq5

4) Listener in variable:

– Tương tự như Activity Is listener, nhưng  khác ở chỗ thay vì implement interface cho Activity thì nó lại được lưu trữ vào một biến có kiểu Listener trong activity. Làm cách này thì ta có thể chia sẻ chung một biến sự kiện cho các control khác nhau.

– Ví dụ bạn xem hình bên dưới:

8_event_12– Bạn thấy đó, ở trên khai báo 1 biến có kiểu listener là interface OnClickListener.

– Và biến này sẽ được chia sẻ cho 2 Button Login và Cancel.

– Bây giờ Tôi sẽ cung cấp ví dụ Chuyển đổi độ F qua C và ngược lại. Bạn xem giao diện bên dưới:
8_event_13– Giao diện bên trên sẽ có 3 button. Ta sẽ tạo một biến sự kiện và chia sẻ cho 3 Button ở trên.

– Bạn xem Outline để thiết kế:

8_event_14– Đây là công thức chuyển đổi:

8_event_15-Bạn xem coding Activity:

import android.os.Bundle;

import android.app.Activity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

public class MainActivity extends Activity {

private Button btnFar,btnCel,btnClear;

private EditText txtFar,txtCel;

private OnClickListener myVarListener=new OnClickListener() {

@Override

public void onClick(View arg0) {

//Lấy F C từ control ở đây

if(arg0==btnFar)

{

//Bạn xử chuyển đổi F–>C theo công thức

}

else if(arg0==btnCel)

{

//Bạn xử chuyển đổi C–>F theo công thức

}

else if(arg0==btnClear)

{

txtFar.setText(“”);

txtCel.setText(“”);

txtFar.requestFocus();

}

}

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btnFar = (Button)findViewById(R.id.btnFar);

btnCel = (Button)findViewById(R.id.btnCel);

btnClear = (Button)findViewById(R.id.btnClear);

txtFar = (EditText)findViewById(R.id.txtFar);

txtCel = (EditText)findViewById(R.id.txtCel);

btnFar.setOnClickListener(myVarListener);

btnCel.setOnClickListener(myVarListener);

btnClear.setOnClickListener(myVarListener);

}

}

Bạn tự viết lệnh cho 2 nút chuyển đổi : cách lấy dữ liệu đã hướng dẫn ở những kiểu lập trình sự kiện trước, bắt buộc bạn phải lấy được. Sau khi lấy được thì chỉ cần ráp vào công thức là xong.

5) Explicit listener class:

– Trường hợp này ta tách riêng một class đóng vai trò là class sự kiện riêng.

– Khi nào lượng coding trong ứng dụng khổng lồ và phức tạp thì ta nên tách class sự kiện riêng để dễ quản lý.

Tôi ví dụ giải phương trình bậc 2, bạn xem giao diện bên dưới:

8_event_16– Khi chọn “Tiếp tục”, chương trình sẽ xóa trắng toàn bộ dữ liệu trên màn hình đồng thời focus tới ô Nhập a.

– Khi chọn “Giải PT”, chương trình sẽ tiến hành lấy thông số a,b,c và tiến hành giải phương trình bậc 2 và cho ra kết quả như hình trên.

– Khi chọn “Thoát”, chương trình sẽ được đóng lại.

– Bạn xem Outline dưới đây:

8_event_17– Tiến hành coding, bạn mở Activity class và coding như bên dưới:

import java.text.DecimalFormat;

import android.os.Bundle;

import android.app.Activity;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.EditText;

import android.widget.TextView;

public class MainActivity extends Activity {

Button btnTieptuc,btnGiai,btnThoat;

EditText edita,editb,editc;

TextView txtkq;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

btnTieptuc=(Button) findViewById(R.id.btntieptuc);

btnGiai=(Button) findViewById(R.id.btngiaipt);

btnThoat=(Button) findViewById(R.id.btnthoat);

btnTieptuc.setOnClickListener(new MyEvent());

btnGiai.setOnClickListener(new MyEvent());

btnThoat.setOnClickListener(new MyEvent());

edita=(EditText) findViewById(R.id.edita);

editb=(EditText) findViewById(R.id.editb);

editc=(EditText) findViewById(R.id.editc);

txtkq=(TextView) findViewById(R.id.txtkq);

}

public void giaiPtb2()

{

String sa=edita.getText()+””;

String sb=editb.getText()+””;

String sc=editc.getText()+””;

int a=Integer.parseInt(sa);

int b=Integer.parseInt(sb);

int c=Integer.parseInt(sc);

String kq=””;

DecimalFormat dcf=new DecimalFormat(“#.00”);

if(a==0)

{

if(b==0)

{

if(c==0)

kq=”PT vô số nghiệm”;

else

kq=”PT vô nghiệm”;

}

else

{

kq=”Pt có 1 No, x=”+dcf.format(-c/b);

}

}

else

{

double delta=b*b-4*a*c;

if(delta<0)

{

kq=”PT vô nghiệm”;

}

else if(delta==0)

{

kq=”Pt có No kép x1=x2=”+dcf.format(-b/(2*a));

}

else

{

kq=”Pt có 2 No: x1=”+dcf.format((-b-Math.sqrt(delta))/(2*a))+

“; x2=”+dcf.format((-b-Math.sqrt(delta))/(2*a));

}

}

txtkq.setText(kq);

}

private class MyEvent implements OnClickListener

{

@Override

public void onClick(View arg0) {

if(arg0==btnTieptuc)

{

edita.setText(“”);

editb.setText(“”);

editc.setText(“”);

edita.requestFocus();

}

else if(arg0.getId()==R.id.btngiaipt)

{

giaiPtb2();

}

else if(arg0.getId()==R.id.btnthoat)

{

finish();

}

}

}

}

– Bạn quan sát coding ở bên trên. Tôi tạo một lớp sự kiện tên là MyEvent, control nào muốn được gán sự kiện chỉ cần gọi lệnh giống như Tôi gán cho Button Giải phương trình:

btnGiai.setOnClickListener(new MyEvent());

– Trong hàm public void onClick(View arg0) . Bạn để ý là lúc thì Tôi so sánh theo Object, lúc thì Tôi lại lấy Id ra để so sánh. Đây là cố ý của Tôi, Tôi muốn nói rằng các bạn có thể kiểm tra xem Button nào sẽ được chọn trên giao diện bằng cách so sánh đối tượng hoặc lấy Id ra để so sánh (tùy ý đồ lập trình của mỗi người)

– Ở đây Tôi có 1 lời khuyên cho các bạn là khi phải xử lý quá nhiều dòng lệnh (lệnh phức tạp) thì bạn nên viết thành từng hàm riêng, và trong hàm xử lý sự kiện  bạn chỉ cần gọi tên hàm mà thôi. Cụ thể là đối với Button “Giải PT” thì Tôi lại viết và gọi riêng hàm giaiPtb2(), còn đối với Button Tiếp tục và Thoát thì Tôi lại không cần thiết viết hàm vì xử lý quá đơn giản.

6. View Subclassing

– Kỹ thuật này không được phổ biến cho lắm. Bạn chỉ sài khi thêm Control động (lúc runtime) vào màn hình. Ta có thể dùng bất kỳ kỹ thuật nào (6 cách Tôi vừa nêu) để thêm sự kiện động cho một Button động.

-Ở cách cuối cùng này thì bạn phải override phương trình performClick của chính Button control:

8_event_18– Như vậy các bạn đã được thực hành về các kiểu lập trình sự kiện trong Android, biết được cách lấy dữ liệu từ EditText, biết xử lý định dạng dữ liệu, củng cổ thêm được Layout.

– Trong các bài tập sắp tới các bạn sẽ được thực hành về Toast & Alert Dialog, và rất nhiều  các control cơ bản cũng như nâng cao trong Android .

– Bạn phải hiểu rõ các kỹ thuật lập trình này để tùy vào từng trường hợp cụ thể mà bạn nên quyết định kỹ thuật nào cho phù hợp.

Chúc các bạn thành công.

Bài tập 7: Làm quen với các Layout trong Android

[polldaddy poll=9764234]

Để thiết kế giao diện tốt cho Android thì trước tiên các bạn phải biết sử dụng một số Layout cơ bản trong Android:

1) Cách tạo Layout và kết nối Layout vào Activity

2) Cách sử dụng HierarchyViewer 

3) Các Layout cơ bản:

  • FrameLayout
  • LinearLayout
  • TableLayout
  • RelativeLayout
  • AbsoluteLayout

*** Đồng thời bạn phải biết kết hợp các Layout này lại với nhau để cho ra được giao diện phức tạp như ý muốn.

– Tôi chỉ nêu ra một số đặc điểm, không thể nói hết ở đây. Các bạn sẽ từ từ cập nhập sau khi đã quen với Layout.

– Trước tiên bạn cần biết cách tạo một Layout mới và cách kết nối nó vào Activity như thế nào:

1) Cách tạo Layout và kết nối Layout vào Activity:

a) Layout mặc định đầu tiên khi bạn tạo một Android Project:

– Khi bạn tạo một Android Project thì mặc nhiên sẽ có một Activity được chỉ định chạy đầu tiên khi bạn thực thi ứng dụng:

7_Layout_0

– Bạn quan sát hình trên: Khi bạn tạo một ứng dụng Android thì mặc nhiên sẽ tạo luôn một Activity để thực thi đầu tiên khi bạn chạy ứng dụng. Ứng với một Activity thì nó sẽ có 1 Layout đi kèm. Trong hình trên thì MainActivity.java (số 1) sẽ có layout đi kèm là activity_main.xml (số 2 – và bạn nhớ luôn là activity_main này sẽ được tự động tạo ra trong thư mục gen của Android, dựa vào đây để ta kết nối Layout vào Activity).

– Như đã nói ở những bài tập trước: Mọi Activity muốn được triệu gọi thành công trong ứng dụng thì bắt buộc nó phải được khai báo trong AndroidManifest.xml (số 3). Bạn double click vào Manifest và nhìn vào vùng số 4, MainActivity được khai báo trong này đồng thời đăng ký là Activity sẽ khởi động lúc ứng dụng được thực thi (xem vùng Tôi bôi màu xanh phần intent-filter).

– Tiếp theo bạn Double – click vào tập tin MainActivity.java:

7_Layout_1

– Nhìn vào hàm onCreate, bạn thấy dòng lệnh : setContentView(R.layout.activity_main); chính là dòng lệnh dùng để kết nối Layout vào Activity. Bạn nhớ là activity_main phải được tự động tạo ra trong gen như hình bên dưới:

7_Layout_2

b) Đổi Layout mặc định bằng một Layout khác bất kỳ:

– Để tạo một Layout mới, bạn click chuột phải vào Project/ chọn New/ chọn Android XML File:

7_Layout_3

– Khi bạn chọn Android XML File thì màn hình bên dưới xuất hiện: Đặt tên cho Layout, chọn kiểu Layout rồi nhấn nút Finish:

7_Layout_4

– Ở trên Tôi đặt tên là : my_new_layout, sau khi nhấn nút Finish bạn quan sát Package Explorer:

7_Layout_5

– Bạn thấy Tôi double – click vào layout : my_new_layout và kéo thả một số control vào giao diện như hình bên trên (bạn nhớ là my_new_layout phải được tự động xuất hiện trong gen – bạn tự kiểm tra).

– Bây giờ bạn vào lại MainActivity.java. Sửa lại dòng lệnh setContentView thành:

7_Layout_6

– Khởi động chương trình và bạn thấy ứng dụng sẽ chạy cái Layout mới này chứ không phải Layout cũ nữa:

7_Layout_7

2) Cách sử dụng HierarchyViewer:

– Như bạn đã biết, một Layout phải được kết nối vào Activity nào đó thông qua hàm setContentView, Android sẽ có cơ chế dịch XML thành Java code:

7_Layout_8

– Ta có thể dùng HierarchyViewer để hiển thị cấu trúc UI của màn hình hiện tại trên emulator hoặc thiết bị thật:

Bạn vào thư mục SDK của bạn / vào thư mục Tools/ rồi chạy tập tin monitor.bat :

7_Layout_9

3) Các Layout cơ bản:

a) FrameLayout:

– Là loại Layout cơ bản nhất, đặc điểm của nó là khi gắn các control lên giao diện thì các control này sẽ luôn được “Neo” ở góc trái trên cùng màn hình, nó không cho phép chúng ta thay đổi vị trí của các control theo một Location nào đó.

– Các control đưa vào sau nó sẽ đè lên trên và che khuất control trước đó (trừ khi ta thiết lập transparent cho control sau):

– Bạn xem đoạn cấu trúc XML dưới này:

<?xml version=”1.0″ encoding=”utf-8″?>

<FrameLayout android:id=”@+id/mainlayout” android:layout_height=”fill_parent” android:layout_width=”fill_parent” android:orientation=”vertical” xmlns:android=”http://schemas.android.com/apk/res/android”>

<ImageView android:layout_height=”wrap_content” android:layout_width=”wrap_content” android:padding=”5px” android:src=”@drawable/blue“/>

<ImageView android:layout_height=”wrap_content” android:layout_width=”wrap_content” android:padding=”5px” android:src=”@drawable/red“/>

</FrameLayout>

7_Layout_10– Bạn thấy đó, hình màu đỏ và màu xanh luôn được “neo” ở góc trái màn hình. Hình màu đỏ đưa vào sau sẽ đè lên trên hình màu xanh.

Chú ý 2 dòng lệnh bên dưới:

– android:src=”@drawable/blue

– android:src=”@drawable/red

Là do ta kéo 2 cái hình tên là blue red vào thư mục drawable của ứng dụng

b) LinearLayout

– Layout này cho phép sắp xếp các control theo 2 hướng trên giao diện: Hướng từ trái qua phải và hướng từ trên xuống dưới.

7_Layout_11

– Bạn có thể dùng margin, gravity, weight để hỗ trợ cho việc thiết kế. Ở đây Tôi không có thời gian nhiều nên chỉ nói đặc điểm chính của LinearLayout, các bạn tự tìm hiểu thêm.

– Ta có thể dùng Properties hỗ trợ sẵn trong Eclipse để thiết lập các thuộc tính cho control:

– Ví dụ như để căn lề các control trên giao diện ta dùng layout_gravity:

7_Layout_12

– hay để căn lề nội dung bên trong của control dùng gravity:

7_Layout_13

– Bạn cũng phải biết so sánh sự khác biệt giữa PaddingMargin:

7_Layout_14

– Ví dụ thay đổi Padding (internal spacing – khoảng cách giữa nội dung bên trong so với đường viền của control):

7_Layout_15

– Ví dụ về đổi Margin (external spacing – khoảng cách giữa control này với control khác):

7_Layout_16

c) TableLayout

-Cho phép sắp các control theo dạng lưới (dòng và cột)

– TableLayout sẽ xem dòng nào có số lượng control nhiều nhất để xác định rằng nó có bao nhiêu cột (lấy dòng có số lượng control nhiều nhất làm số cột chuẩn).

7_Layout_17

– Như vậy theo hình trên thì bạn phải nói là TableLayout này có 4 cột, 3 dòng.

– Dùng layout_span để trộn các cột:

7_Layout_19

– Dùng layout_column để di chuyển vị trí của control đến một cột nào đó trên 1 dòng:

7_Layout_20– Dùng stretchColumns để dãn đều các control, các cell (ta thường dùng dấu “*”):

7_Layout_21d) RelativeLayout:

– RelativeLayout cho phép sắp xếp các control theo vị trí tương đối giữa các control khác trên giao diện (kể cả control chứa nó). Thường nó dựa vào Id của các control khác để sắp xếp theo vị trí tương đối. Do đó khi làm RelativeLayout bạn phải chú ý là đặt Id control cho chuẩn xác, nếu sau khi Layout xong mà bạn lại đổi Id của các control thì giao diện sẽ bị xáo trộn (do đó nếu đổi ID thì phải đổi luôn các tham chiếu khác sao cho khớp với Id bạn mới đổi).

– Dưới đây là ví dụ về cách sử dụng RelativeLayout (bạn để ý những dòng tô đậm):

7_Layout_22– Ta có thể sử dụng công cụ trong Eclipse để thiết kế :

7_Layout_23e) AbsoluteLayout:

– Cho phép thiết lập các control giao diện theo vị trí tùy thích:

7_Layout_24

– Như vậy các Tôi đã giới thiệu sơ qua cách tạo Layout và cách sử dụng một số Layout cụ thể, tùy từng trường hợp mà các bạn ứng dụng vào. Thông thường ứng với mỗi một ứng dụng cụ thể thì bạn phải kết hợp nhiều loại Layout lại với nhau.

– Bạn cần hiểu rõ các loại Layout để giúp ích cho quá trình thiết kế giao diện

– Bài tập sau Tôi sẽ hướng dẫn các bạn cách sử dụng một số control cơ bản và cách viết sự kiến cho Button như thế nào.

Chúc các bạn thành công.