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

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:


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

-Đặ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:


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

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


<?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>

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


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

Xem MainActivity.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;
 }
 });
 }
}

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

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

– Xem nội dung từng class:

– Abstract class Employee:


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

– class EmployeeFullTime:


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

– Class EmployeePartTime:


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

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


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

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

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

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

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

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

51 responses

  1. […] bài tập 13 bạn đã được thực hành với ListView control. Trong bài tập này bạn sẽ học […]

  2. xin hỏi thầy giáo là sau khi mình bỏ đoạn : /* 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; */ của ví dụ Vidu_ListView_ArrayList thì khi chạy vẫn k thay đổi ! Mong thầy giải thích dùm mình 🙂 cảm ơn

    1. Chỗ này là xử lý sự kiện long click mà bạn, bạn thử click chuột lâu một tí thì sẽ thấy sự khác nhau. Bạn chưa đọc kĩ lý thuyết của thầy rồi. Thân.

      1. Phạm Văn Đoàn

        thầy cho e hỏi là đổ dữ liệu vào listView nhưng listView ấy lại ở 1 activity mới thì làm thế nào ạ

      2. Cách làm tương tự, em chỉ cần chuyển danh sách qua Activity mới là xong.

  3. Ths!Bai thuc hanh that huu ich!

  4. trường hợp 2 dòng: final String arr[]=getResources().getStringArray(R.array.myarray);
    phải để trong onCreate mới chạy

  5. mình muốn hiển thị listview gồm image + textview thì chuổi image dc truyền ntn và gọi là ntn vậy AD? Tks AD

    1. xem bài 14

  6. Thầy ơi!
    Cho em hỏi nếu số lượng mẫu tin trong database khoảng hơn 1 triệu mẫu thì nếu như làm theo cách thông thường thì có bao nhiểu thì cứ bỏ vào mãng rồi đổ vào listview vậy thì em thấy không ổn. Như em được biết thì trong .net có hỗ trợ cái này (mình tạo bộ nhớ đệm). Còn android không biết mình làm cách nào để giải quyết vấn đề này vậy thầy?
    Mong Thầy trả lời giúp.!

  7. […] Vấn đề này đã được thầy Trần Duy Thanh viết rất đầy đủ so với những gì mình biết rồi. Đánh dấu lại dây có gì tìm cho dễ . Cảm ơn thầy vì bài viết! Bài tập 13: Thực hành về ListView trong Android […]

  8. cám ơn thầy bài viết rất hữu ích

  9. Thầy ơi cho em hỏi làm theo trường hợp 5 mà mình muốn chạm nhấn giữ vào items trong listView để xóa một items thì mình phải gọi sự kiện gì ra ạ. Trong lớp ListActivity không có phương thức setOnItemLongClickListener(){};

    1. // lấy listview từ ListActivity –> dùng cái listview đó gọi ham giống như listview
      ListView lv = getListView();
      lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {

      @Override
      public boolean onItemLongClick(AdapterView arg0, View arg1,

      }
      });

  10. cuong.hust.bg@gmail.com | Reply

    Thưa thầy , em muốn lấy kích thước số phần tử trong list view thì lám tn ạ

    1. lít viu chấm size();

  11. Em muốn viết thêm hàm tìm kiếm 1 phần tử trong tất cả các phần tử của listview có được không? và làm như thế nào? Cảm ơn thầy

  12. quá hay bạn ạ. thanks nhìu…

  13. Cho em hỏi public String toString() {
    // TODO Auto-generated method stub
    return super.toString() +” –>FullTime=”+TinhLuong();
    super ở đây làm gì vậy mọi người ?\

    1. BeginerAndroid | Reply

      viết super.toString()
      thay cho
      this.id+” – “+this.name(Chính là hàm toString ở lớp cha)

  14. Thầy cho em hỏi dùng ListView bằng ListActivity có gì khác hoặc tối ưu hơn không ạ (ngoài cách code ra)

  15. […] Bài tập 13: Thực hành về ListView trong AndroidIn “2. Xử lý giao diện người dùng” […]

  16. […] Bài tập 13: Thực hành về ListView trong AndroidIn “2. Xử lý giao diện người dùng” […]

  17. Cám ơn Thầy vì những bài viết rất chi tiết ạ.

  18. Cám ơn Thầy vì những bài viết Listview quá nhiều nội dung hay và đầy đủ chọn vẹn.

  19. Bai viet rat de hieu. Cam on thay.

  20. itrinhnhut@yahoo.com | Reply

    Cảm ơn thầy, những bài học của thầy rất hay. Em tự học ở nhà nên không định hướng được phải bắt đầu từ đâu, học những gì trước, đi theo những bài học của thầy rất dễ hiểu.

  21. adapter.notifyDataSetChanged(); // Cái này đâu có cập nhật lại giao diện đâu thầy ?
    E muốn sau khi add,update,delete item trong list thì List nó cập nhật lại ngay (không cần gọi đến hàm showdata(load lại dữ liệu) ) thì phải làm ntn thầy ?

  22. thầy ơi ! em muốn bắt các sự kiện khác nhau cho từng thành phần của listview thì làm thế nào ạ ?

  23. thầy ơi ví dụ như cái trường hợp 5 ấy ạ. nếu em sử dụng trình đơn menu cho phép chọn edit hoặc deleted nếu chọn edit thì dữ liệu “samsung” được đưa sang activity khác để chỉnh sửa và load lại trong listview thì làm thế nào hả thầy? em có dử dụng cơ sở dữ liệu ạ

  24. nguyễn sĩ anh | Reply

    Mặc dù không học thầy nhưng em rất cảm ơn những bài viết hay và rất chi tiết của thầy

    1. tui cũng thế nek :v

  25. em bị dính lỗi không chạy được vd 5

  26. Thưa thầy cho em hỏi,
    Trong trường hợp số 4, nếu trong lớp cha có nhiều hơn 1 phương thức vd toString1, toString2,… (cụ thể trong source của thầy chỉ có 1 phương thức là toString) thì lúc adapter thay đổi nó sẽ gọi hàm nào ạ?

    1. Em quên mất đó là @Override 😀

  27. Thầy cho em hỏi em muốn thay đổi giao diện màn hình điện thoại dùng listview thì là thế nào ạ.

  28. Em xin hỏi thầy là em mới bắt đầu học Android vậy thì nếu em học tốt hết tất cả các chương mà thấy hướng dẫn trên đây thì em có đủ kiến thức để làm được apps chưa ạ ? Hay em cần phải học thêm những gì nữa ?

  29. ad cho hoi la khi click vao samsung ma muon no hien ra noi dung cua samsung thi phai lam sao

  30. bài viết rất hay nhưng mà e thấy code sai ad ạ !! em code toàn ko báo lỗi nhưng cũng ko chạy được ra đúng như thế ? ko hiểu sao

    1. mình viết đc hết bạn nha. chạy dc 100%

  31. cảm ơn nhiều
    TrungĐinh

  32. kha la hay, cam on tac gia

  33. Cám ơn thầy vì những bài học bổ ích! 😀

  34. Thay oi cho em hoi cách viết code kiểm tra dưx liệu trùng lặp trước khi thêm vào Listview ạ

  35. Em cảm ơn thầy đã tận tình chỉ dẫn khá chi tiết về Android ạ!
    dạ thầy cho em hỏi một tí về trường hợp 3 ạ!
    -giả sử em tạo 1 button xoá.
    -nếu bây giờ em muốn click vào 1 phần tử trong listview rồi sao đó sử dụng button để xoá thì em nên làm sao ạ?
    dạ em cảm ơn thầy nhiều.

  36. Em cảm ơn thầy
    Thầy có thể làm một bài viết về RecyclerView được không ạ? Em thấy mọi người hay dùng RecyclerView

    1. Trong khóa học Online Thầy đã cập nhật

Leave a reply to Dinh Ha Trung Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.