Category Archives: 3. Thực hành về Intent

Bài tập 26: Dùng Implicit Intent để viết chương trình gọi điện thoại và nhắn tin SMS


– Ở bài tập 24bài tập 25 Tôi đã hướng dẫn rất kỹ về cách sử dụng Intent (các intent này còn gọi là Explicit Intent).

– Trong bài tập 26 Tôi sẽ hướng dẫn bạn cách sử dụng Implicit Intent (bạn cứ hiểu nôm na là những Intent được xây dựng sẵn, được cung cấp sẵn trong hệ điều hành Android). Tạm thời bạn cứ hiểu như vậy đi, nếu như Tôi sai thì Tôi sẽ sửa lại sau, vì có thể có nhiều cách hiểu khác hay hơn Tôi nhiều.

– Tôi đặt vấn đề như sau:

+ Một ngày đẹp trời khủng khiếp nào đó chẳng hạn 3h giờ ngày 13 tháng 3 năm 2013, “Dế” đáng ghét của bạn bị rớt xuống nền nhà cái bạch bạch bạch…. bị mẻ, méo mấy miếng và hư luôn chương trình gọi điện thoại và nhắn tin SMS (bị hư 2 chức năng này, nhưng mà “Dế Mẻ” đó vẫn hoạt động). Không ai thèm sửa Dế cho bạn, xui cái bạn đang học Android lớp của Tôi, Tôi yêu cầu bạn phải tự lập trình ra chức năng Gọi điện thoại và nhắn tin SMS cho Dế đó (dĩ nhiên thiết bị của bạn sử dụng Android OS). Vậy bạn phải làm rồi, vì không làm sẽ bị 0 điểm.

+ Vậy dùng những kỹ thuật nào để có thể viết được chức năng nghe gọi+ nhắn tin SMS thay thế cho chương trình có sẵn của Android?

+ Tôi sẽ hướng dẫn các bạn vào buổi sau, bạn hãy chú ý theo dõi. Trong thời gian chờ đợi thì Tôi khuyên các bạn phải làm đi làm lại bài tập 24 và bài tập 25.

Tôi giới hạn bài tập này như sau: Bài tập này đơn thuần chỉ là cho phép nhập tên và số điện thoại vào bộ nhớ (không phải danh bạ điện thoại) sau đó hiển thị danh sách này vào ListView, ListView sẽ cung cấp ContextMenu có 2 mục: “Gọi điện thoại” và “Nhắn tin”. Qua phần Content Provider và Telephony API các bạn sẽ được học kỹ hơn về cách lấy danh bạ từ điện thoại ra, cách đọc tin nhắn trong inbox ra, cách tương tác với danh bạ và tin nhắn… Nên bài tập này các bạn xem nó như là “Chơi chơi” vui thôi.

– Mấu chốt của bài này là các bạn phải tự biết cách tạo một cuộc gọi, cách gửi tin nhắn trong Android như thế nào, mấy phần “râu ria” khác các bạn đừng bận tâm.

– Để có thể gọi điện thoại và nhắn tin thì các bạn phải khai báo trong Manifest các permission sau:

<uses-permission android:name=”android.permission.CALL_PHONE” />
<uses-permission android:name=”android.permission.SEND_SMS” />

– Bạn xem giao diện của chương trình:

26_sms_0– Nhấn “Save Contact” để lưu thông tin vào ListView như hình.

– Xử lý context menu cho ListView:

26_sms_1– Chức năng “Call to …” để gọi, màn hình gọi sẽ hiện ra như bên dưới:

26_sms_2– Chức năng “Send Sms to …“, cho ra màn hình gửi tin nhắn như bên dưới:

26_sms_3– Nhấn “Send Message” để gửi. Ở đây Tôi muốn nói các bạn rằng có 2 hành vi gửi tin nhắn.

1) gửi tin nhắn mà không biết kết quả thành công hay không (dễ dàng, những mà không nên. Trường hợp này thường xuyển sảy ra. Tôi lấy cụ thể trường hợp của Tôi, nhà Tôi ở trên Núi sóng thường yếu và không liên lạc được, nếu viết theo cách này thì Bạn sẽ không biết là gửi cho Tôi thành công hay không.)

Ví dụ: Viết như bên dưới thì có thể gửi được tin nhắn ở trường hợp bình thường, không kiểm tra kết quả trả về (Còn kiểm tra kết quả trả về bạn xem trong coding đầy đủ).

final SmsManager sms = SmsManager.getDefault();

sms.sendTextMessage(  0987773061″, null, “Hello teo teo!”, null, null);

2) gửi tin nhắn có kiểm tra kết quả thành công (ta nên dùng cách này, nhưng mà khó vì các bạn chưa học IntentFilter, nhưng Tôi vẫn đưa vào, có gì các bạn tìm hiểu sau)

– Bây giờ bạn xem cấu tạo chương trình:

26_sms_4– Giao diện chính activity_main.xml:

26_sms_5

– Xem source 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" >

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

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

<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_span="2"
 android:background="#008000"
 android:gravity="center"
 android:text="&quot;Chơi Chơi&quot; Phone Utility"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />
 </TableRow>

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

<TextView
 android:id="@+id/textView2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Name:" />

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

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

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

<TextView
 android:id="@+id/textView3"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Phone:" />

<EditText
 android:id="@+id/editPhone"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:ems="10"
 android:inputType="phone" />
 </TableRow>

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

<Button
 android:id="@+id/btnSaveContact"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_column="1"
 android:text="Save Contact" />
 </TableRow>
 </TableLayout>

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

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

</LinearLayout>

– Các XML resource khác các bạn tự xem trong project.

– Class MyContact:


package tranduythanh.com;

import java.io.Serializable;

public class MyContact implements Serializable{
 /**
 *
 */
 private static final long serialVersionUID = 1L;
 private String name;
 private String phone;
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public String getPhone() {
 return phone;
 }
 public void setPhone(String phone) {
 this.phone = phone;
 }
 public MyContact(String name, String phone) {
 super();
 this.name = name;
 this.phone = phone;
 }
 public MyContact() {
 super();
 }
 @Override
 public String toString() {
 return this.name+"["+this.phone+"]";
 }
}

– Class xử lý MainActivity:


package tranduythanh.com;

import java.util.ArrayList;

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class MainActivity extends Activity {

EditText editName,editPhone;
 Button btnSave;
 ListView lvContact;
 //Danh sách contact để đưa vào ListView
 ArrayList<MyContact>arrContact=new ArrayList<MyContact>();
 ArrayAdapter<MyContact>adapter=null;
 MyContact selectedContact=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 doGetFormWidgets();
 doAddEvents();
 }
 public void doGetFormWidgets()
 {
 btnSave=(Button) findViewById(R.id.btnSaveContact);
 editName=(EditText) findViewById(R.id.editName);
 editPhone=(EditText) findViewById(R.id.editPhone);
 lvContact=(ListView) findViewById(R.id.lvContact);
 //tạo đối tượng adapter
 adapter=new ArrayAdapter<MyContact>
 (this, android.R.layout.simple_list_item_1,arrContact);
 //gán Adapter vào cho ListView
 lvContact.setAdapter(adapter);
 //thiết lập contextmenu cho ListView
 registerForContextMenu(lvContact);
 }
 public void doAddEvents()
 {
 btnSave.setOnClickListener(new OnClickListener() {

@Override
 public void onClick(View arg0) {
 // TODO Auto-generated method stub
 doSaveContact();
 }
 });
 //lấy contact được chọn trước đó trong ListView
 //Vì khi mở context menu sẽ làm mất focus nên ta phải lưu lại trước
 //khi mở context menu
 lvContact.setOnItemLongClickListener(new OnItemLongClickListener() {

@Override
 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
 int arg2, long arg3) {
 //lưu vết contact được chọn trong ListView
 selectedContact=arrContact.get(arg2);
 return false;
 }
 });
 }
 /**
 * mỗi lần nhấn Save contact thì gọi hàm này
 * để cập nhạt contact vào List view
 * bạn lưu ý là ta chỉ làm trong bộ nhớ
 * không phải lưu vào Danh Bạ (phần này học sau)
 */
 public void doSaveContact()
 {
 MyContact ct=new MyContact();
 ct.setName(editName.getText()+"");
 ct.setPhone(editPhone.getText()+"");
 arrContact.add(ct);
 adapter.notifyDataSetChanged();
 }
 @Override
 public void onCreateContextMenu(ContextMenu menu, View v,
 ContextMenuInfo menuInfo) {
 // TODO Auto-generated method stub
 super.onCreateContextMenu(menu, v, menuInfo);
 //gắn context menu vào
 getMenuInflater().inflate(R.menu.phonecontextmenu, menu);
 menu.setHeaderTitle("Call- Sms");
 menu.getItem(0).setTitle("Call to "+selectedContact.getPhone());
 menu.getItem(1).setTitle("Send sms to "+selectedContact.getPhone());
 }
 @Override
 public boolean onContextItemSelected(MenuItem item) {
 //kiểm tra xem Menu Item nào được chọn
 switch(item.getItemId())
 {
 case R.id.mnuCall:
 doMakeCall();
 break;
 case R.id.mnuSms:
 doMakeSms();
 break;
 case R.id.mnuRemove:
 arrContact.remove(selectedContact);
 adapter.notifyDataSetChanged();
 break;
 }
 return super.onContextItemSelected(item);
 }
 /**
 * Thực hiện gọi điện thoại
 */
 public void doMakeCall()
 {
 Uri uri=Uri.parse("tel:"+selectedContact.getPhone());
 Intent i=new Intent(Intent.ACTION_CALL, uri);
 startActivity(i);
 }
 /**
 * thực hiện mở giao diện gửi tin nhắn
 * Truyền thông tin contact đang chọn qua
 * activity mới
 */
 public void doMakeSms()
 {
 Intent i=new Intent(this, MySMSActivity.class);
 Bundle b=new Bundle();
 b.putSerializable("CONTACT", selectedContact);
 i.putExtra("DATA", b);
 startActivity(i);
 }
}

-Bạn xem dòng lệnh 96 – thiết lập tiêu đề cho context menu

– Dòng lệnh  97,98  để sửa lại title cho các menuitem ứng với mỗi contact.

– Dòng lệnh 121 có hàm doMakeCall để gọi điện thoại cho số nào đó. Bạn nhìn vào nội dung bên trong để xem quy tắc tạo lệnh gọi.

– Class xử lý gửi tin nhắn MySMSActivity:


package tranduythanh.com;

import android.os.Bundle;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.SmsManager;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MySMSActivity extends Activity {

Button btnSendSMS;
 EditText editContent;
 TextView txtSendTo;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_my_sms);
 btnSendSMS =(Button) findViewById(R.id.btnSendSms);
 editContent =(EditText) findViewById(R.id.editSMS);
 txtSendTo=(TextView) findViewById(R.id.txtSendTo);
 //Lấy thông tin từ Intent
 Intent i =getIntent();
 Bundle b=i.getBundleExtra("DATA");
 final MyContact c=(MyContact) b.getSerializable("CONTACT");
 btnSendSMS.setOnClickListener(new OnClickListener() {

@Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 sendSms(c);
 }
 });
 txtSendTo.setText("Send to : "+c.getPhone());
 }
 /**
 * hàm dùng để gửi tin nhắn có kiểm tra kết quả trả về
 * Tôi chưa giải thích ở đây được vì nó liên quan rất nhiều
 * kiến thức, khi nào tới Broadcast Receiver, telephony Tôi sẽ
 * giải thích lại
 * @param c
 */
 public void sendSms(MyContact c)
 {
 //lấy mặc định SmsManager
 final SmsManager sms = SmsManager.getDefault();
 Intent msgSent = new Intent("ACTION_MSG_SENT");
 //Khai báo pendingintent để kiểm tra kết quả
 final PendingIntent pendingMsgSent =
 PendingIntent.getBroadcast(this, 0, msgSent, 0);
 registerReceiver(new BroadcastReceiver() {
 public void onReceive(Context context, Intent intent) {
 int result = getResultCode();
 String msg="Send OK";
 if (result != Activity.RESULT_OK) {
 msg="Send failed";
 }
 Toast.makeText(MySMSActivity.this, msg,
 Toast.LENGTH_LONG).show();
 }
 }, new IntentFilter("ACTION_MSG_SENT"));
 //Gọi hàm gửi tin nhắn đi
 sms.sendTextMessage(c.getPhone(), null, editContent.getText()+"",
 pendingMsgSent, null);
 finish();
 }
}

– Dòng lệnh 51 có hàm sendSms để gửi tin nhắn đi. hàm này Tôi viết có kiểm tra kết quả gửi thành công hay không. Tôi không giải thích nhiều vì nó liên quan tới quá nhiều kiến thức. Tạm thời bạn cố gắng hiểu từng dòng lệnh Tôi giải thích ở bên trong là ok rồi.

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

– Bài này là tiền đề để làm các ứng dụng khác liên quan tới Telephony.

– Đến đây coi như bạn đã tạm ổn vê Intent. Bài tập kế tiếp Tôi sẽ hướng dẫn các bạn làm về Đa ngôn ngữ trong Android, đã nói tới Mobile thì thường nó phải hỗ trợ đa ngôn ngữ (cả thế giới đều sài, với những ngôn ngữ khác nhau).

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

Bài tập 25: Tiếp tục củng cố kiến thức Intent, ví dụ tổng hợp Quản Lý Nhân Viên


– Ở bài tập 24 bạn đã hiểu cơ bản về Intent

– Bài tập này Tôi chủ ý viết thật phức tạp lên để các bạn tập trung công lực tìm hiểu nó.

– Xin lỗi vì để các bạn chờ lâu mới cập nhật bài tập này.

– Bây giờ Tôi tiếp tục hướng dẫn các bạn tìm hiểu sâu về Android cũng như ôn tập lại các thành phần đã học trước đó.

– Bài tập này Tôi cũng chủ ý giải thích ít đi (vì đã giải thích quá nhiều ở các bài tập trước rồi). Bài tập này bạn phải tập suy luận logic để hiểu nó sâu hơn.

– Tôi tin chắc rằng nếu như bạn hiểu bài tập 25 này thì bạn có thể viết được một chương trình Android ra trò rồi. Vì nó là tổng hợp của các kiến thức về Android mà Tôi đã trình bày từ trước tới giờ.

– Mục tiêu của bài tập này:

——————————————————————————

– Thao tác nhuần nhuyễn với Intent

– Ôn tập lại các control thường hay sử dụng

– Nhuần nhuyễn với ListView

–  Xử lý Checked (radio, Checkbox) trong ListView

– Nhuần nhuyễn với Custom Layout

– Biết cách sử dụng Enum

– Cách sử dụng chung Layout cho các Activity

– … và đón nhận thêm một số ý tưởng sáng tạo trong lập trình.

——————————————————————————

– Bài này rất là khó và phức tạp, nhưng đổi lại nó rất hay. Tôi hi vọng bài tập này sẽ giúp ích cho các bạn rất nhiều trong việc khám phá Android. Vì vậy Tôi khuyên các bạn hãy chăm chỉ làm đi làm lại bài này.

– Mô tả chương trình:

+ Chương trình cho phép quản lý nhân viên + phòng ban.

+ Mỗi phòng ban sẽ có nhiều nhân viên, phòng ban cần lưu trữ (mã phòng ban, tên phòng ban)

+ Một phòng ban sẽ có Trưởng phòng và Phó phòng. Trưởng phòng thì chỉ có 1, phó phòng thì số lượng không giới hạn (hoặc không có)

+ Thông tin nhân viên : Mã nhân viên, tên nhân viên, giới tính (nam, nữ), chức vụ (trưởng phòng, phó phòng, nhân viên)

+ Chương trình cho phép:

  • Thêm/sửa/ xóa phòng ban
  • Thêm / sửa / xóa nhân viên
  • cho phép nhân viên chuyển phòng ban
  • cho phép thiết lập ban lãnh đạo phòng ban (trưởng phó)
  • và một số chức năng khác

Sau đây là demo giao diện chính của chương trình:

25_intent_0

– Tôi giải thích về màn hình chính như sau:

+ Nút “Lưu Phòng Ban“: Cho phép lưu phòng ban và cập nhật vào ListView. Nếu mã phòng ban đã tồn tại thì tự động cập nhật, còn mã phòng ban chưa tồn tại thì phải thêm mới.

+ Sự kiện nhấn trên ListView: nhấn vào phòng ban nào thì hiển thị lại thông tin của phòng ban đó vào phần edittext bên trên.

+ ListView phải sử dụng Custom Layout, Ta phải tự thiết kế Layout cho ListView bên trên:

* Mỗi phần tử ListView có chứa 2 TextView, TextView 1 dùng để hiển thị mã phòng ban và tên phòng ban, chú ý phải cho người sử dụng biết Phòng ban này có nhân viên hay chưa có, nếu có nhân viên thì có bao nhiêu người (xem hình trên).

* Mỗi phòng ban phải cho biết Trưởng Phòng và phó phòng là ai (xem hình)

* Ví dụ bạn nhìn vào phòng Kỹ Thuật: Bạn thấy thông tin phòng ban và số nhân viên trong phòng ban là 3. Và Trưởng Phòng tên là “Đoàn Ái Nương“. Có 2 Phó Phòng là “Trần Đạo Đức” và “Nguyễn Đại Tài“.

*Phòng dịch vụ thì chưa có nhân viên nào cả

*Phòng Truyền Thông thì có 3 nhân viên nhưng chỉ có 1 trưởng phòng là “Nguyễn Thị Téo“.

– Tiếp tục xử lý Context Menu cho ListView Phòng ban:

25_intent_1– Khi nhấn thật lâu vào một phòng ban nào đó, ví dụ trường hợp trên là phòng Kỹ Thuật, chương trình sẽ hiển thị context Menu có 4 chức năng:

1.  Thêm nhân viên

2.  Xem danh sách nhân viên

3. Lập trưởng/ phó phòng

4. và xóa phòng ban.

– Ứng với mỗi chức năng ta có:

1. Thêm nhân viên:

– Mặc định mỗi một nhân viên mới được tạo ra thì chỉ có chức vụ là Nhân Viên (không có chức quản lý):

25_intent_2

– Nút “xóa trắng “: cho phép xóa dữ liệu trên EditText và focus tới mã nhân viên

– Nút “Lưu nhân viên”, cho phép thêm mới nhân viên vào phòng ban, Giới Tính Nam, Nữ để hiển thị hình ảnh cho đúng.

– Sau khi bấm nút “Lưu nhân viên”, thì cập nhật lại danh sách phòng ban (cập nhập số lượng nhân viên cho phòng ban).

– Ví dụ ở hình trên bây giờ Tôi bấm “Lưu nhân viên”, màn hình này sẽ tắt đi để hiển thị lại màn hình chính, nhưng trong phòng ban Kỹ Thuật số lượng nhân viên sẽ tăng lên là 4, xem hình:

25_intent_3

2.  Xem danh sách nhân viên:

– Chương trình sẽ hiện thị danh sách nhân viên của phòng ban đang chọn, ví dụ trong trường hợp này là xem danh sách nhân viên của phòng ban Kỹ thuật:

25_intent_4

– Như bạn thấy đó. Màn hình xem danh sách nhân viên có các chức năng sau:

+ Nút mũi tên “BacK” cho phép trở về màn hình chính.

+Nhân viên có hình theo giới tính (nam, nữ)

+ Nhân viên có mô tả: Chức vụ, giới tình

+ Vậy ta cũng phải dùng Custom layout

– Bây giờ ta xem  chức năng  Context Menu cho ListVỉew của mục xem danh sách nhân viên:

25_intent_5

– Vậy màn hình này có 3 chức năng:

2.1 Sửa nhân viên

2.2 Chuyển phòng ban

2.3 xóa nhân viên

– Ta vào từng chức năng:

2.1 Sửa nhân viên:

– Ở ví dụ trên là ta nhấn thật lâu vào nhân viên tên “Trần Đạo Đức“, sau đó Context Menu hiển thị lên, ta chọn sửa nhân viên, màn hình sửa xuất hiện như sau (chú ý là Activity sửa nhân viên sử dụng chung Layout với Activity thêm nhân viên):

25_intent_6

– Thông tin của nhân viên “Trần Đạo Đức” sẽ được hiển thị như trên. Mã nhân viên sẽ cấm thay đổi, còn các chức năng khác là y xì như trong màn hình thêm mới nhân viên.

– Trong trường hợp này Tôi sửa “Trần Đạo Đức” thành “Trần Thế” và nhấn nút “Lưu nhân viên” thì màn hình này đóng lại để trở về màn hình xem danh sách, bạn quan sát sự thay đổi như sau:

25_intent_7

2.2 Chuyển phòng ban:

– Bây giờ ta vào chức năng chuyển phòng ban cho nhân viên. Chương trình sẽ hiển thị danh sách phòng ban (có RadioButton ở bên cạnh cho phép chuyển phòng ban).

– Bây giờ Tôi chọn “Trần Thế” và chuyển qua phòng Dịch vụ (Nhấn thật lâu vào Trần Thế, context menu hiển thị ra thì ta chọn Chức năng Chuyển phòng ban):

25_intent_8

– Sau khi chọn phòng ban để chuyển, nhấn nút có hình “Apply”, chương trình sẽ quay lại màn hình xem danh sách nhân viên, lúc này Bạn không còn thấy nhân viên Trần Thế nữa, bởi vì nhân viên này đã được chuyển qua phòng dịch vụ:

25_intent_9

– Bạn có thể kiểm tra lại bằng cách bấm nút “Back” để trở về màn hình chính, trong màn hình chính sẽ xuất hiện 1 nhân viên mà ta vừa chuyển:

25_intent_10

2.3 xóa nhân viên

– bây giờ ta qua chức năng Xóa nhân viên trong màn hình xem danh sách, chương trình sẽ hiển thị màn hình hỏi xem có chắc chắn muốn xóa hay không? nhấn đồng ý để xóa:

– Ví dụ Tôi chọn nhân viên tên “Trần Duy Thanh” rồi xóa:

25_intent_11

3. Lập trưởng/ phó phòng:

– bây giờ ta qua chức năng Lập trưởng / phó phòng cho mỗi phòng ban (tại màn hình chính).

– Khi context Menu hiển thị lên thì ta chọn “Lập trưởng. phó phòng”:

– Ví dụ, bây giờ Tôi nhấn thật lâu vào phòng ban “Truyền Thông”, sau đó Tôi thiết lập trưởng phó phòng lại cho phòng ban này, xem giao diện bên dưới:

25_intent_12

– Sau khi chọn “lập trưởng/ phó phòng”, thì chương trình hiển thị màn hình thiết lập như bên dưới:

25_intent_13

– Trưởng phòng thì chỉ cho phép chọn 1 (dùng Radio Button)

– Phó phòng cho phép chọn tùy ý (dùng Checkbox)

– Ta dùng layout có sẵn của android (không phải custom layout), chỉ viết lại sự kiện onclick cho ListView nó hiểu mà thôi.

– Sau khi chọn Trưởng/ phó, click “Apply ” thì chương trình trở về màn hình chính,  quan sát:

25_intent_14

– Bạn thấy đó, Trưởng phòng và phó phòng đã được cập nhật.

4. và xóa phòng ban.

– Ta qua chức năng cuối cùng: Xóa phòng ban, tưởng tự như xóa nhân viên. CHương trình cũng hỏi ta có chắc chắn muốn xóa hay không?

25_intent_15

– Như vậy Tôi đã mô tả xong yêu cầu của bài toán. Bây giờ Tôi đi chi tiết vào coding:

– Bạn xem cấu trúc thư mục của Android Project:

25_intent_21

– Bạn quan sát trong phần Source Code Tôi chia ra làm 3 Package:

1) tranduythanh.com.model -> dùng để viết mô hình hóa đối tượng

2) tranduythanh.com.adapter -> dùng để viết Customlayout cho ListView

3) tranduythanh.com.activity –> dùng để lưu trữ các Activity

– Bây giờ ta vào package :  tranduythanh.com.model :

25_intent_17

– Package này có 3 class và 1 enum chức vụ (thực ra enum cũng là một class đặc biệt).

– Coding enum ChucVu.java:


package tranduythanh.com.model;
/**
 * Enum này để thiết lập chức vụ cho nhân viên
 * @author drthanh
 *
 */
public enum ChucVu {
 //Muốn gán được như thế này: TruongPhong("Trưởng Phòng")
 //thì phải có constructor ChucVu(String cv)
 TruongPhong("Trưởng Phòng"),
 PhoPhong("Phó Phòng"),
 NhanVien("Nhân Viên");
 private String cv;
 ChucVu(String cv)
 {
 this.cv=cv;
 }
 public String getChucVu()
 {
 return this.cv;
 }
}

– Coding Infor.java:


package tranduythanh.com.model;

import java.io.Serializable;
/**
 * Class này để lưu mã và tên là class cha của NhanVien
 * và PhongBan. Vì cả nhân viên hay phòng ban đều có mã và tên
 * @author drthanh
 *
 */
public class Infor implements Serializable{
 /**
 *
 */
 private static final long serialVersionUID = 1L;
 private String ma;
 private String ten;
 public Infor(String ma, String ten) {
 super();
 this.ma = ma;
 this.ten = ten;
 }
 public Infor() {
 super();
 }
 public String getMa() {
 return ma;
 }
 public void setMa(String ma) {
 this.ma = ma;
 }
 public String getTen() {
 return ten;
 }
 public void setTen(String ten) {
 this.ten = ten;
 }
 @Override
 public String toString() {
 // TODO Auto-generated method stub
 return this.ma+" - "+this.ten;
 }
}

– Coding NhanVien.java:


package tranduythanh.com.model;

import java.io.Serializable;
/**
 * Class lưu trữ thông tin nhân viên
 * @author drthanh
 *
 */
public class NhanVien extends Infor implements Serializable{
 /**
 *
 */
 private static final long serialVersionUID = 1L;
 private boolean gioitinh;
 private ChucVu chucvu;
 private PhongBan phongban;
 public NhanVien(String ma, String ten, boolean gioitinh, ChucVu chucvu,
 PhongBan phongban) {
 super(ma,ten);
 this.gioitinh = gioitinh;
 this.chucvu = chucvu;
 this.phongban = phongban;
 }
 public NhanVien(String ma, String ten, boolean gioitinh) {
 super(ma,ten);
 this.gioitinh = gioitinh;
 }
 public NhanVien() {
 super();
 }
 public boolean isGioitinh() {
 return gioitinh;
 }
 public void setGioitinh(boolean gioitinh) {
 this.gioitinh = gioitinh;
 }
 public ChucVu getChucvu() {
 return chucvu;
 }
 public void setChucvu(ChucVu chucvu) {
 this.chucvu = chucvu;
 }
 public PhongBan getPhongban() {
 return phongban;
 }
 public void setPhongban(PhongBan phongban) {
 this.phongban = phongban;
 }
 @Override
 public String toString() {
 // TODO Auto-generated method stub
 return super.toString();
 }
}

– Coding PhongBan.java:


package tranduythanh.com.model;

import java.io.Serializable;
import java.util.ArrayList;
/**
 * Class để lưu thông tin phòng ban
 * @author drthanh
 *
 */
public class PhongBan extends Infor implements Serializable{

private static final long serialVersionUID = 1L;
 private ArrayList<NhanVien>dsnv=new ArrayList<NhanVien>();
 public PhongBan(String ma, String ten) {
 super(ma,ten);
 }
 public PhongBan() {
 super();
 }
 /**
 * Hàm cho phép thêm một nhân viên mới
 * nếu nhân viên có mã tồn tại rồi thì
 * tự động trở thành cập nhật
 * @param nv
 */
 public void themNv(NhanVien nv)
 {
 int i=0;
 for(;i<dsnv.size();i++)
 {
 NhanVien nvOld=dsnv.get(i);
 if(nvOld.getMa().trim().equalsIgnoreCase(nv.getMa().trim()))
 {
 break;
 }
 }
 if(i<dsnv.size())
 dsnv.set(i, nv);
 else
 dsnv.add(nv);
 }
 public NhanVien get(int index)
 {
 return dsnv.get(index);
 }
 public int size()
 {
 return dsnv.size();
 }
 /**
 * hàm trả về trưởng phòng của phòng ban
 * Nếu chưa có trưởng phòng thì trả về null
 * @return
 */
 public NhanVien getTruongPhong()
 {
 for(int i=0;i<dsnv.size();i++)
 {
 NhanVien nv=dsnv.get(i);
 if(nv.getChucvu()==ChucVu.TruongPhong)
 return nv;
 }
 return null;
 }
 /**
 * hàm trả về danh sách phó trưởng phòng
 * vì 1 phòng ban có thể có nhiều phó phòng
 * Nếu không có phó phòng nào thì danh sách
 * có kích thước =0
 * @return
 */
 public ArrayList<NhanVien>getPhoPhong()
 {
 ArrayList<NhanVien> dsPhoPhong=new ArrayList<NhanVien>();
 for(NhanVien nv: dsnv)
 {
 if(nv.getChucvu()==ChucVu.PhoPhong)
 dsPhoPhong.add(nv);
 }
 return dsPhoPhong;
 }
 public ArrayList<NhanVien> getListNhanVien()
 {
 return this.dsnv;
 }
 @Override
 public String toString() {
 // TODO Auto-generated method stub
 String str=super.toString();
 if(dsnv.size()==0)
 str+="(Chưa có NV)";
 else
 str+="(có "+dsnv.size()+" NV)";
 return str;
 }
}

– Bây giờ ta qua package tranduythanh.com.adapter:

25_intent_18

– 2 Adapter này dùng để custom layout cho danh sách Phòng ban và danh sách nhân viên.

– Chú ý là cả 2 Adapter này đều dùng chung 1 Layout tên “layout_item_custom.xml“:

25_intent_19

– Bạn xem source XML của  “layout_item_custom.xml“:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >

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

<ImageView
 android:id="@+id/imgview"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 />

<TextView
 android:id="@+id/txtShortInfor"
 android:layout_width="match_parent"
 android:layout_height="wrap_content" />

</LinearLayout>

<TextView
 android:id="@+id/txtDetailInfor"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:textColor="#000080"
 android:textSize="10sp"
 android:textStyle="italic" />

</LinearLayout>

– Bây giờ ta xem cách custom layout thông qua ADapter (phần customlayout Tôi đã hướng dẫn ở các bài tập trước, bạn tự xem lại):

– Coding PhongBanAdapter.java:


package tranduythanh.com.adapter;

import java.util.ArrayList;

import tranduythanh.com.activity.R;
import tranduythanh.com.model.NhanVien;
import tranduythanh.com.model.PhongBan;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
/**
 * Class này dùng để custom layout cho Danh sách phòng ban
 * @author drthanh
 *
 */
public class PhongBanAdapter extends ArrayAdapter<PhongBan> {
 Activity context;
 int layoutId;
 ArrayList<PhongBan> arrPhongBan;
 public PhongBanAdapter(Activity context, int textViewResourceId,
 ArrayList<PhongBan> objects) {
 super(context, textViewResourceId, objects);
 this.context=context;
 this.layoutId=textViewResourceId;
 this.arrPhongBan=objects;
 }
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 //gán layout vào coding
 convertView=context.getLayoutInflater().inflate(layoutId, null);
 //lấy các control ra theo id
 TextView txtpb= (TextView) convertView.findViewById(R.id.txtShortInfor);
 TextView txtmotapb= (TextView) convertView.findViewById(R.id.txtDetailInfor);
 //Lấy phòng ban thứ position
 PhongBan pb=arrPhongBan.get(position);
 txtpb.setText(pb.toString());
 /**
 * Các Dòng lệnh dưới này để kiểm tra Trưởng phòng, phó phòng
 */
 String strMota="";
 String tp="Trưởng Phòng: [Chưa có]";
 NhanVien nv=pb.getTruongPhong();
 if(nv!=null)
 {
 tp="Trưởng Phòng: ["+nv.getTen()+"]";
 }
 ArrayList<NhanVien> dsPp=pb.getPhoPhong();
 String pp="Phó phòng: [Chưa có]";
 if(dsPp.size()>0)
 {
 pp="Phó phòng:\n";
 for(int i=0;i<dsPp.size();i++)
 {
 pp+=(i+1)+". "+dsPp.get(i).getTen()+"\n";
 }
 }
 strMota=tp+"\n"+pp;
 //gán thông tin cho phần chi tiết
 txtmotapb.setText(strMota);
 return convertView;
 }

}

– Coding NhanVienAdapter.java, Ở phòng ban Tôi không sử dụng ImageView, còn ở Nhân viên Tôi sử dụng ImageView :


package tranduythanh.com.adapter;

import java.util.ArrayList;

import tranduythanh.com.activity.R;
import tranduythanh.com.model.NhanVien;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
/**
 * Class để tạo customlayout cho danh sách nhân viên
 * ImageVIew để hiển thị hình ảnh theo giới tính
 * @author drthanh
 *
 */
public class NhanVienAdapter extends ArrayAdapter<NhanVien> {

Activity context;
 int layoutId;
 ArrayList<NhanVien> arrNhanVien;
 public NhanVienAdapter(Activity context, int textViewResourceId,
 ArrayList<NhanVien> objects) {
 super(context, textViewResourceId, objects);
 this.context=context;
 this.layoutId=textViewResourceId;
 this.arrNhanVien=objects;
 }
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {
 //gán XML layout vào coding
 convertView=context.getLayoutInflater().inflate(layoutId, null);
 //lấy các control ra
 TextView txtnv= (TextView) convertView.findViewById(R.id.txtShortInfor);
 TextView txtmotanv= (TextView) convertView.findViewById(R.id.txtDetailInfor);
 ImageView img=(ImageView) convertView.findViewById(R.id.imgview);
 //lấy nhân viên thứ position
 NhanVien nv=arrNhanVien.get(position);
 txtnv.setText(nv.toString());
 String strMota="";
 String cv="Chức vụ: "+nv.getChucvu().getChucVu();
 String gt="Giới tính: "+(nv.isGioitinh()?"Nữ":"Nam");
 //Kiểm tra giới tính để gán cho đúng hình đại diện
 img.setImageResource(R.drawable.girlicon);
 if(!nv.isGioitinh())
 img.setImageResource(R.drawable.boyicon);
 strMota=cv+"\n"+gt;
 txtmotanv.setText(strMota);
 return convertView;
 }

}

– Bây giờ ta qua package tranduythanh.com.activity:

25_intent_20

– Ta lần lượt vào từng màn hình theo thứ tự.

– Màn hình chính (MainActivity.java):

– Bạn xem Outline của màn hình chính chính:

25_intent_22

– Đây là XML source của MainActivity:


<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="Chương trình quản lý nhân viên"
 android:textColor="#FFFFFF"
 android:textSize="20sp" />

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

<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ã Phòng Ban:" />

<EditText
 android:id="@+id/editmapb"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 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 Phòng Ban:" />

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

</TableRow>

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

<Button
 android:id="@+id/btnluupb"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_column="1"
 android:text="Lưu Phòng Ban" />

</TableRow>
 </TableLayout>

<TextView
 android:id="@+id/textView4"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008000"
 android:text="Danh sách phòng ban"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />

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

</LinearLayout>

– Ta xem xử lý coding của MainActivity:


package tranduythanh.com.activity;

import java.util.ArrayList;

import tranduythanh.com.activity.R;
import tranduythanh.com.adapter.PhongBanAdapter;
import tranduythanh.com.model.ChucVu;
import tranduythanh.com.model.NhanVien;
import tranduythanh.com.model.PhongBan;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
/**
 * Class MainActivity của ứng dụng
 * @author drthanh
 *
 */
public class MainActivity extends Activity {
 //Khai báo các Request + Result code để xử lý Intent for result
 public static final int MO_ACTIVITY_THEM_NHAN_VIEN=1;
 public static final int MO_ACTIVITY_SUA_NHAN_VIEN=2;
 public static final int THEM_NHAN_VIEN_THANHCONG=3;
 public static final int SUA_NHAN_VIEN_THANHCONG=4;
 public static final int XEM_DS_NHAN_VIEN=5;
 public static final int CAPNHAT_DS_NHAN_VIEN_THANHCONG=6;
 public static final int MO_ACTIVITY_THIET_LAP_TP_PP=7;
 public static final int THIET_LAP_TP_PP_THANHCONG=8;
 public static final int MO_ACTIVITY_CHUYENPHONG=9;
 public static final int CHUYENPHONG_THANHCONG=10;

 private Button btnLuuPb;
 private EditText editMapb,editTenpb;
 private ListView lvpb;
 private static ArrayList<PhongBan>arrPhongBan=new ArrayList<PhongBan>();
 //ở đây dùng PhongBanAdapter
 private PhongBanAdapter adapterPb=null;
 private PhongBan pbSelected=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 getFormWidgets();
 addEvents();
 fakeData();
 }
 /**
 * Hàm này dùng để tải dữ liệu tạm (đỡ phải nhập mỏi tay)
 * Tôi dùng hàm này để ví dụ cho lẹ
 * bạn có thể xóa nó đi (nói chung vô thưởng vô phạt)
 */
 public void fakeData()
 {
 NhanVien nv=null;
 PhongBan pb=new PhongBan("pb1", "Kỹ thuật");
 nv=new NhanVien("m4", "Đoàn Ái Nương", true);
 nv.setChucvu(ChucVu.TruongPhong);
 pb.themNv(nv);
 nv=new NhanVien("m5", "Trần Đạo Đức", false);
 nv.setChucvu(ChucVu.PhoPhong);
 pb.themNv(nv);
 nv=new NhanVien("m6", "Nguyễn Đại Tài", false);
 nv.setChucvu(ChucVu.PhoPhong);
 pb.themNv(nv);
 arrPhongBan.add(pb);
 pb=new PhongBan("pb2", "Dịch vụ");
 arrPhongBan.add(pb);
 pb=new PhongBan("pb3", "Truyền thông");
 arrPhongBan.add(pb);
 nv=new NhanVien("m1", "Nguyễn Văn Tẻo", false);
 nv.setChucvu(ChucVu.NhanVien);
 pb.themNv(nv);
 nv=new NhanVien("m2", "Nguyễn Thị Téo", true);
 nv.setChucvu(ChucVu.TruongPhong);
 pb.themNv(nv);
 nv=new NhanVien("m3", "Nguyễn Văn Teo", false);
 nv.setChucvu(ChucVu.NhanVien);
 pb.themNv(nv);

 adapterPb.notifyDataSetChanged();
 }
 /**
 * - Hàm này để load các control theo Id
 * - Thiết lập Adapter cho ListView phòng ban
 * - thiết lập context Menu cho ListView
 */
 public void getFormWidgets()
 {
 btnLuuPb=(Button) findViewById(R.id.btnluupb);
 editMapb=(EditText) findViewById(R.id.editmapb);
 editTenpb=(EditText) findViewById(R.id.editTenpb);
 lvpb=(ListView) findViewById(R.id.lvphongban);
 //khởi tạo đối tượng phòng ban adapter
 //dùng layout_item_custom.xml
 adapterPb=new PhongBanAdapter(this,
 R.layout.layout_item_custom,
 arrPhongBan);
 lvpb.setAdapter(adapterPb);
 //Đăng ký contextmenu cho Listview
 registerForContextMenu(lvpb);
 }
 /**
 * hàm gán sự kiện cho các control: button, ListView
 */
 public void addEvents()
 {
 //Bấm lưu để lưu phòng ban
 btnLuuPb.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View arg0) {
 // TODO Auto-generated method stub
 doLuuPhongBan();
 }
 });
 //xử lý lưu biến tạm khi nhấn long - click
 //phải dùng cái này để biết được trước đó đã chọn item nào
 lvpb.setOnItemLongClickListener(new OnItemLongClickListener() {

@Override
 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
 int arg2, long arg3) {
 //lưu vết lại đối tượng thứ arg2 trong danh sách
 pbSelected=arrPhongBan.get(arg2);
 return false;
 }

 });
 }
 /**
 * hàm xử lý lưu phòng ban
 * đơn thuần là đưa phòng ban mới vào ArrayList
 * chú ý bạn phải kiểm tra trùng lắp Id, hay các
 * thông tin đã đầy đủ chưa ở đây
 * gọi adapterPb.notifyDataSetChanged(); để cập nhật ListView
 */
 public void doLuuPhongBan()
 {
 String mapb=editMapb.getText()+"";
 String tenpb=editTenpb.getText()+"";
 PhongBan pb=new PhongBan(mapb, tenpb);
 arrPhongBan.add(pb);
 adapterPb.notifyDataSetChanged();
 }
 /**
 * hàm này để gán COntextMenu vào ứng dụng
 * đã học từ lâu rồi, phải tự hiểu
 */
 @Override
 public void onCreateContextMenu(ContextMenu menu, View v,
 ContextMenuInfo menuInfo) {
 super.onCreateContextMenu(menu, v, menuInfo);
 getMenuInflater().inflate(R.menu.contextmenu_phongban, menu);
 }
 /**
 * hàm này để xử lý người sử dụng vừa chọn menuitem nào
 * ta dựa vào Id để xử lý
 */
 @Override
 public boolean onContextItemSelected(MenuItem item) {
 switch(item.getItemId())
 {
 case R.id.mnuthemnv:
 doThemNhanVien();
 break;
 case R.id.mnudanhsachnv:
 doDanhSachNhanVien();
 break;
 case R.id.mnutruongphong:
 doThietLapLanhDao();
 break;
 case R.id.mnuxoapb:
 doXoaPhongBan();
 break;
 }
 return super.onContextItemSelected(item);
 }
 /**
 * khi chọn menu Thêm nhân viên, đơn thuần chỉ là hiển thị
 * màn hìn thêm nhân viên (với dạng Dialog)
 * nhớ là dùng startActivityForResult
 * do đó ta lắng nghe kết quả tại hàm onActivityResult
 */
 public void doThemNhanVien()
 {
 Intent i=new Intent(this, ThemNhanVienActivity.class);
 startActivityForResult(i, MO_ACTIVITY_THEM_NHAN_VIEN);
 }
 /**
 * hàm onActivityResult để xử lý kết quả trả về
 * sau khi gọi startActivityForResult kết thúc
 */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 // TODO Auto-generated method stub
 super.onActivityResult(requestCode, resultCode, data);
 //màn hình thêm mới nhân viên trả kết quả về
 if(resultCode==THEM_NHAN_VIEN_THANHCONG)
 {
 //Cách lấy dữ liệu đã học rồi, ko nói lại
 Bundle bundle= data.getBundleExtra("DATA");
 NhanVien nv= (NhanVien) bundle.getSerializable("NHANVIEN");
 pbSelected.themNv(nv);
 adapterPb.notifyDataSetChanged();
 }
 //Màn hình thiết lập lạnh đão/ cập nhật danh sách trả
 //kết quả về
 else if(resultCode==THIET_LAP_TP_PP_THANHCONG||
 resultCode==CAPNHAT_DS_NHAN_VIEN_THANHCONG)
 {
 //Cách lấy dữ liệu đã học rồi, ko nói lại
 Bundle bundle= data.getBundleExtra("DATA");
 PhongBan pb= (PhongBan) bundle.getSerializable("PHONGBAN");
 //đơn thuần là xóa danh sách cũ
 pbSelected.getListNhanVien().clear();
 //rồi cập nhật lại toàn bộ danh sách mới
 //sinh viên có thể chọn giải pháp thông minh hơn
 //tức là phần tử nào bị ảnh hưởng thì xử lý phần tử đó
 pbSelected.getListNhanVien().addAll(pb.getListNhanVien());
 adapterPb.notifyDataSetChanged();
 }
 }
 /**
 * hàm cho phép danh xem danh sách nhân viên của phòng
 * ban đang chọn, đơn thuần là mở DanhSachNhanVienActivity
 * và truyền phòng ban qua -->toàn bộ danh sách nhân viên
 * sẽ được hiển thị trong DanhSachNhanVienActivity
 */
 public void doDanhSachNhanVien()
 {
 Intent i=new Intent(this, DanhSachNhanVienActivity.class);
 Bundle bundle=new Bundle();
 bundle.putSerializable("PHONGBAN", pbSelected);
 i.putExtra("DATA", bundle);
 startActivityForResult(i, XEM_DS_NHAN_VIEN);
 }
 /**
 * hàm cho phép mở màn hình thiết lập lãnh đạo phòng ban
 * Trưởng phòng và phó phòng
 * ThietLapTruongPhongActivity sẽ có 2 ListView
 * - Listview 1 hiển thị dang radiobutton để chỉ chọn 1 trưởng phòng
 * - ListView 2 hiển thị dạng Checkbox cho phép chọn nhiều phó phòng
 */
 public void doThietLapLanhDao()
 {
 Intent i=new Intent(this, ThietLapTruongPhongActivity.class);
 Bundle bundle=new Bundle();
 bundle.putSerializable("PHONGBAN", pbSelected);
 i.putExtra("DATA", bundle);
 startActivityForResult(i, MO_ACTIVITY_THIET_LAP_TP_PP);
 }
 /**
 * hàm cho phép xóa phòng ban đang chọn
 */
 public void doXoaPhongBan()
 {
 AlertDialog.Builder builder=new AlertDialog.Builder (this);
 builder.setTitle("Hỏi xóa");
 builder.setMessage("Bạn có chắc chắn muốn xóa ["+pbSelected.getTen()+"]");
 builder.setIcon(android.R.drawable.ic_input_delete);
 builder.setNegativeButton("Không", new DialogInterface.OnClickListener() {

 @Override
 public void onClick(DialogInterface arg0, int arg1) {
 // TODO Auto-generated method stub
 arg0.cancel();
 }
 });
 builder.setPositiveButton("Ừ", new DialogInterface.OnClickListener() {

 @Override
 public void onClick(DialogInterface dialog, int which) {
 // TODO Auto-generated method stub
 arrPhongBan.remove(pbSelected);
 adapterPb.notifyDataSetChanged();
 }
 });
 builder.show();
 }
 /**
 * Tôi cố tình cung cấp hàm này để ở các Activity khác đều
 * có thể truy suất được danh sách phòng ban tổng thể
 * @return
 */
 public static ArrayList<PhongBan> getListPhongBan()
 {
 return arrPhongBan;
 }
}

– Ta qua màn hình thêm nhân viên. Chú ý là màn hình này bạn phải cấu hình mở dạng Dialog.

– xem layout:

25_intent_23

– Bạn xem XML source code của màn hình này:


<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=".ThemNhanVienActivity" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008000"
 android:text="Thông Tin Nhân Viên"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />

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

<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/editMaNV"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 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/editTenNV"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 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="Giới Tính:" />

<RadioGroup
 android:id="@+id/radioGroup1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:orientation="horizontal" >

<RadioButton
 android:id="@+id/radNam"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:checked="true"
 android:text="Nam" />

<RadioButton
 android:id="@+id/radNu"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Nữ" />
 </RadioGroup>

</TableRow>

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

<Button
 android:id="@+id/btnxoatrang"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Xóa trắng" />

<Button
 android:id="@+id/btnluunv"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Lưu nhân viên" />

</TableRow>
 </TableLayout>

</LinearLayout>

– Giờ ta xem xử lý coding cho phần thêm nhân viên (ThemNhanVienActivity):


package tranduythanh.com.activity;

import tranduythanh.com.activity.R;
import tranduythanh.com.model.ChucVu;
import tranduythanh.com.model.NhanVien;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
/**
 * class này cho phép thêm mới một nhân viên vào
 * Phòng ban đang chọn
 * @author drthanh
 *
 */
public class ThemNhanVienActivity extends Activity {

private Button btnXoaTrang,btnLuuNhanVien;
 private EditText editManv,editTenNv;
 private RadioButton radNam;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_them_nhan_vien);
 getFormWidgets();
 addEvents();
 }
 /**
 * hàm lấy các control theo id
 */
 public void getFormWidgets()
 {
 btnXoaTrang=(Button) findViewById(R.id.btnxoatrang);
 btnLuuNhanVien=(Button) findViewById(R.id.btnluunv);
 editManv=(EditText) findViewById(R.id.editMaNV);
 editTenNv=(EditText) findViewById(R.id.editTenNV);
 radNam=(RadioButton) findViewById(R.id.radNam);
 }
 /**
 * hàm gán sự kiện
 */
 public void addEvents()
 {
 btnXoaTrang.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View arg0) {
 // TODO Auto-generated method stub
 doXoaTrang();
 }
 });
 btnLuuNhanVien.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 doLuuNhanVien();
 }
 });
 }
 /**
 * đơn thuần là xóa trắng dữ liệu của các control
 * rồi focus tới mã
 */
 public void doXoaTrang()
 {
 editManv.setText("");
 editTenNv.setText("");
 editManv.requestFocus();
 }
 /**
 * hàm lưu nhân viên theo phòng ban
 * truyền nhân viên qua MainActivity
 * MainActivity có nhiệm vụ lấy được nhân viên này
 * và đưa họ vào phòng ban chọn lúc nãy
 */
 public void doLuuNhanVien()
 {
 NhanVien nv=new NhanVien();
 nv.setMa(editManv.getText()+"");
 nv.setTen(editTenNv.getText()+"");
 nv.setChucvu(ChucVu.NhanVien);
 nv.setGioitinh(!radNam.isChecked());
 Intent i=getIntent();
 Bundle bundle=new Bundle();
 bundle.putSerializable("NHANVIEN", nv);
 i.putExtra("DATA", bundle);
 setResult(MainActivity.THEM_NHAN_VIEN_THANHCONG, i);
 finish();
 }
}

– Tiếp tục ta xem màn hình Xem danh sách nhân viên:

– bạn xem outline:

25_intent_24

– Xem XML Resource của activity_danh_sach_nhan_vien.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=".DanhSachNhanVienActivity" >

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

<ImageButton
 android:id="@+id/btnback"
 android:layout_width="16dp"
 android:layout_height="16dp"
 android:contentDescription="TODO"
 android:src="@drawable/back" />

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

</LinearLayout>

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

</LinearLayout>

– Xem coding xử lý phần xem danh sách nhân viên (DanhSachNhanVienActivity) :

– Class này rất phức tạp, nó còn chứa Context menu để cho phép:

+ Sửa nhân viên

+ Chuyển phòng ban cho nhân viên

+ Xóa nhân viên:


package tranduythanh.com.activity;

import java.util.ArrayList;

import tranduythanh.com.activity.R;
import tranduythanh.com.adapter.NhanVienAdapter;
import tranduythanh.com.model.NhanVien;
import tranduythanh.com.model.PhongBan;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
/**
 * class này dùng để hiển thị danh sách nhân viên
 * Class này cũng phức tạp không kém MainActivity
 * nhớ là dùng custom layout
 * - Hiển thị danh sách
 * - cho phép chỉnh sửa
 * - cho phép chuyển phòng ban
 * - cho phép xóa nhân viên
 * @author drthanh
 *
 */
public class DanhSachNhanVienActivity extends Activity {

TextView txtmsg;
 ImageButton btnback;
 ListView lvNhanvien;
 ArrayList<NhanVien> arrNhanvien=null;
 //Nhân viên Adapter để hiển thị thông tin
 //và chi tiết : chức vụ, giới tính
 NhanVienAdapter adapter=null;
 PhongBan pb=null;
 private NhanVien nvSelected=null;
 private int position=-1;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_danh_sach_nhan_vien);
 txtmsg=(TextView) findViewById(R.id.txtmsg);
 btnback=(ImageButton) findViewById(R.id.btnback);
 lvNhanvien=(ListView) findViewById(R.id.lvnhanvien);
 getDataFromMain();
 addEvents();
 registerForContextMenu(lvNhanvien);
 }
 /**
 * hàm lấy giá trị từ MainActivity
 * sẽ truyền phòng ban qua
 * bên này lấy phòng ban và dựa vào phòng ban này
 * lấy ra danh sách nhân viên
 */
 public void getDataFromMain()
 {
 Intent i=getIntent();
 Bundle b=i.getBundleExtra("DATA");
 pb= (PhongBan) b.getSerializable("PHONGBAN");
 arrNhanvien=pb.getListNhanVien();
 adapter=new NhanVienAdapter(this,
 R.layout.layout_item_custom,
 arrNhanvien);
 lvNhanvien.setAdapter(adapter);
 txtmsg.setText("DS nhân viên ["+pb.getTen()+"]");
 }
 /**
 * hàm gán sự kiện (đã quá quen thuộc rồi)
 * có lưu vết lại nhân viên vừa chọn để xử lý
 * cho contextmenu
 */
 public void addEvents()
 {
 btnback.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View arg0) {
 doUpdateToMain();
 }
 });
 lvNhanvien.setOnItemLongClickListener(new OnItemLongClickListener() {

@Override
 public boolean onItemLongClick(AdapterView<?> arg0, View arg1,
 int arg2, long arg3) {
 nvSelected=arrNhanvien.get(arg2);
 position=arg2;
 return false;
 }

 });
 }
 /**
 * hàm gán context menu(đã quá quen thuộc)
 */
 @Override
 public void onCreateContextMenu(ContextMenu menu, View v,
 ContextMenuInfo menuInfo) {
 // TODO Auto-generated method stub
 super.onCreateContextMenu(menu, v, menuInfo);
 getMenuInflater().inflate(R.menu.contextmenu_nhanvien, menu);
 }
 /**
 * hàm xử lý sự kiện chọn menuitem (đã quen thuộc quá)
 */
 @Override
 public boolean onContextItemSelected(MenuItem item) {
 // TODO Auto-generated method stub
 switch(item.getItemId())
 {
 case R.id.mnusuanv:
 doSuaNhanVien();
 break;
 case R.id.mnuchuyenpb:
 doChuyenPhongBan();
 break;
 case R.id.mnuxoanv:
 doXoaNhanVien();
 break;
 }
 return super.onContextItemSelected(item);
 }
 /**
 * hàm onActivityResult xử lý kết quả trả về
 * cho trường hợp xử dụng COntext Menu để mở các
 * Activity khác
 */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 // TODO Auto-generated method stub
 super.onActivityResult(requestCode, resultCode, data);
 //lấy kết quả sửa nhân viên thành công
 if(resultCode==MainActivity.SUA_NHAN_VIEN_THANHCONG)
 {
 Bundle b=data.getBundleExtra("DATA");
 NhanVien nv= (NhanVien) b.getSerializable("NHANVIEN");
 arrNhanvien.set(position, nv);
 adapter.notifyDataSetChanged();
 }
 //lấy kết quả chuyển phòng ban thành công
 else if(resultCode==MainActivity.CHUYENPHONG_THANHCONG)
 {
 arrNhanvien.remove(nvSelected);
 adapter.notifyDataSetChanged();
 }
 }
 /**
 * hàm sửa nhân viên
 * đơn giản là mở Activity sửa nhân viên lên
 * rồi truyền nhân viên đang chọn qua Activity đó
 *
 */
 public void doSuaNhanVien()
 {
 Intent i=new Intent(this, SuaNhanVienActivity.class);
 Bundle b=new Bundle();
 b.putSerializable("NHANVIEN", nvSelected);
 i.putExtra("DATA", b);
 startActivityForResult(i, MainActivity.MO_ACTIVITY_SUA_NHAN_VIEN);
 }
 /**
 * hàm chuyển phòng ban cho nhân viên đang chọn
 * đơn thuần là mở Activity chuyển phòng ban
 * Activity này có nhiệm vụ hiển thị toàn bộ phòng ban
 * rồi cho phép người sử dụng chọn phòng ban để chuyển
 */
 public void doChuyenPhongBan()
 {
 Intent i=new Intent(this, ChuyenPhongBanActivity.class);
 Bundle b=new Bundle();
 b.putSerializable("NHANVIEN", nvSelected);
 i.putExtra("DATA", b);
 startActivityForResult(i, MainActivity.MO_ACTIVITY_CHUYENPHONG);
 }
 /**
 * hàm cho phép xóa nhân viên hiện tại
 * (đã quen thuộc quá)
 */
 public void doXoaNhanVien()
 {
 AlertDialog.Builder builder=new AlertDialog.Builder (this);
 builder.setTitle("Hỏi xóa");
 builder.setMessage("Bạn có chắc chắn muốn xóa ["+nvSelected.getTen()+"]");
 builder.setIcon(android.R.drawable.ic_input_delete);
 builder.setNegativeButton("Không", new DialogInterface.OnClickListener() {

 @Override
 public void onClick(DialogInterface arg0, int arg1) {
 // TODO Auto-generated method stub
 arg0.cancel();
 }
 });
 builder.setPositiveButton("Ừ", new DialogInterface.OnClickListener() {

 @Override
 public void onClick(DialogInterface dialog, int which) {
 // TODO Auto-generated method stub
 arrNhanvien.remove(nvSelected);
 adapter.notifyDataSetChanged();
 }
 });
 builder.show();
 }
 /**
 * khi nhấn nút Back (hình back)
 * thì truyền thông số về MainActivity để cập nhật
 * phòng ban
 */
 public void doUpdateToMain()
 {
 Intent i=getIntent();
 Bundle b=new Bundle();
 b.putSerializable("PHONGBAN", pb);
 i.putExtra("DATA", b);
 setResult(MainActivity.CAPNHAT_DS_NHAN_VIEN_THANHCONG, i);
 finish();
 }
}

– Ta tiếp tục làm việc với màn hình sửa nhân viên, vì màn hình này sử dụng chung Layout với màn hình thêm nhân viên. Nên Tôi chỉ mô tả phần xử lý coding mà thôi (SuaNhanVienActivity):


package tranduythanh.com.activity;

import tranduythanh.com.model.NhanVien;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RadioButton;
/**
 * class này cho phép sửa nhân viên được chọn trong Danhsachnhanvien
 * sử dụng chung Layout với Thêm nhân viên
 * Không cho sửa mã số nhân viên
 * khi bấm lưu thì cập nhật lại (rất đơn giản)
 * @author drthanh
 *
 */
public class SuaNhanVienActivity extends Activity{
 EditText editMa,editTen;
 RadioButton radNam;
 Button btnClear,btnSave;
 NhanVien nv=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_them_nhan_vien);
 getFormWidgets();
 getDefaultData();
 addEvents();
 }
 /**
 * hàm lấy các control theo id
 */
 public void getFormWidgets()
 {
 editMa=(EditText) findViewById(R.id.editMaNV);
 editTen=(EditText) findViewById(R.id.editTenNV);
 radNam=(RadioButton) findViewById(R.id.radNam);
 editMa.setEnabled(false);
 editTen.requestFocus();

 btnClear=(Button) findViewById(R.id.btnxoatrang);
 btnSave=(Button) findViewById(R.id.btnluunv);
 }
 /**
 * hàm lấy giá trị từ DanhSachNhanVienActivity truyền qua
 * để hiển thị
 */
 public void getDefaultData()
 {
 Intent i =getIntent();
 Bundle b=i.getBundleExtra("DATA");
 nv=(NhanVien) b.getSerializable("NHANVIEN");
 editMa.setText(nv.getMa());
 editTen.setText(nv.getTen());
 radNam.setChecked(true);
 if(nv.isGioitinh())
 radNam.setChecked(false);
 }
 public void addEvents()
 {
 btnClear.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View arg0) {
 // TODO Auto-generated method stub
 editTen.setText("");
 editTen.requestFocus();
 }
 });
 /**
 * bấm lưu thì đóng cửa sổ sửa này
 * và truyền dữ liệu qua màn hình cha để nó tự cập nhật
 */
 btnSave.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View v) {
 // TODO Auto-generated method stub
 Intent i =getIntent();
 nv.setTen(editTen.getText()+"");
 nv.setGioitinh(!radNam.isChecked());
 Bundle b=new Bundle();
 b.putSerializable("NHANVIEN", nv);
 i.putExtra("DATA", b);
 setResult(MainActivity.SUA_NHAN_VIEN_THANHCONG, i);
 finish();
 }
 });
 }
}

– Ta qua màn hình chuyển phòng ban cho nhân viên:

– Bạn xem layout XML:

25_intent_25– Màn hình này là màn hình con của màn hình Xem danh sách nhân nhiên (lúc dùng Context Menu).

– Khi chọn nhân viên nào thì sẽ tiến hành mở màn hình chuyển phòng ban cho nhân viên đó.

– xem XML Resource:


<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=".ChuyenPhongBanActivity" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008000"
 android:text="Chọn phòng ban để chuyển"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />

<ListView
 android:id="@+id/lvphongban"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_weight="3" >
 </ListView>

<ImageButton
 android:id="@+id/imgapply"
 android:layout_width="32dp"
 android:layout_height="32dp"
 android:layout_gravity="center"
 android:contentDescription="Thiết lập"
 android:src="@drawable/apply" />

</LinearLayout>

– Bạn xem xử lý coding cho phần chuyển phòng ban:


package tranduythanh.com.activity;

import java.util.ArrayList;

import tranduythanh.com.model.NhanVien;
import tranduythanh.com.model.PhongBan;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageButton;
import android.widget.ListView;
/**
 * Class dùng để xử lý chuyển phòng ban cho nhân viên
 * @author drthanh
 *
 */
public class ChuyenPhongBanActivity extends Activity {

ListView lvPb;
 private static ArrayList<PhongBan>arrPhongBan=null;
 ArrayAdapter<PhongBan>adapter;
 ImageButton btnApply;
 NhanVien nv=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_chuyen_phong_ban);
 getFormWidgets();
 //lấy nhân viên từ màn hình xem danh sách nhân viên
 Intent i=getIntent();
 Bundle b= i.getBundleExtra("DATA");
 nv=(NhanVien) b.getSerializable("NHANVIEN");
 }
 /**
 * hàm lấy control theo id
 * đồng thời load toàn bộ danh sách phòng ban ở MainActivity
 * lên ListView để sử dụng
 * android.R.layout.simple_list_item_single_choice ->dùng Radio
 * Bắt buộc phải xử lý hàm: lvPb.setOnItemClickListener
 * để gán checked cho Radio
 */
 public void getFormWidgets()
 {
 lvPb=(ListView) findViewById(R.id.lvphongban);
 btnApply=(ImageButton) findViewById(R.id.imgapply);

 arrPhongBan=MainActivity.getListPhongBan();
 adapter=new ArrayAdapter<PhongBan>
 (this, android.R.layout.simple_list_item_single_choice,
 arrPhongBan);
 lvPb.setAdapter(adapter);

lvPb.setOnItemClickListener(new OnItemClickListener() {

boolean somethingChecked = false;
 @Override
 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
 long arg3) {
 //hiển nhiên View arg1 là CheckedTextView
 if(somethingChecked){
 CheckedTextView cv = (CheckedTextView) arg1;
 cv.setChecked(false);

}
 CheckedTextView cv = (CheckedTextView) arg1;
 if(!cv.isChecked())
 {
 cv.setChecked(true);
 arrPhongBan.get(arg2).themNv(nv);
 }
 somethingChecked=true;
 }
 });
 //khi chọn nút Apply thì tiến hành đóng màn hình này
 //và truyền lệnh về cho DanhSachNhanVienACtivity
 btnApply.setOnClickListener(new OnClickListener() {

@Override
 public void onClick(View arg0) {
 doApply();

}
 });
 }
 public void doApply()
 {
 setResult(MainActivity.CHUYENPHONG_THANHCONG);
 finish();
 }
}

– Ta qua màn hình cuối cùng: Thiết lập trưởng phó phòng cho nhân viên

– Màn hình này là màn hình con của MainActivity.

– Khi chọn phòng ban nào thì thiết lập trưởng phó phòng cho phòng ban đó.

– xem Layout (activity_thiet_lap_truong_phong.xml):

25_intent_26

– Xem XML resource:

</pre>
<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=".ThietLapTruongPhongActivity" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008000"
 android:text="Chọn trưởng phòng"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />

<ListView
 android:id="@+id/lvtruongphong"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_weight="3" >

</ListView>

<TextView
 android:id="@+id/textView2"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:background="#008000"
 android:text="Chọn phó phòng"
 android:textColor="#FFFFFF"
 android:textSize="15sp" />

<ListView
 android:id="@+id/lvphophong"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:layout_weight="2" >
 </ListView>

<ImageButton
 android:id="@+id/imgapply"
 android:layout_width="32dp"
 android:layout_height="32dp"
 android:layout_gravity="center"
 android:contentDescription="Thiết lập"
 android:src="@drawable/apply" />

</LinearLayout>
<pre>

– xem xử lý coding:


package tranduythanh.com.activity;

import java.util.ArrayList;

import tranduythanh.com.activity.R;
import tranduythanh.com.model.ChucVu;
import tranduythanh.com.model.NhanVien;
import tranduythanh.com.model.PhongBan;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageButton;
import android.widget.ListView;
import android.app.Activity;
import android.content.Intent;
/**
 * màn hình sẽ hiển thị danh sách nhân viên vào 2 ListView khác nhau
 * ListView 1 dùng Radio để chọn trưởng phòng
 * ListView 2 dùng Checkbox để chọn phó phòng
 * @author drthanh
 *
 */
public class ThietLapTruongPhongActivity extends Activity {

ListView lvtruongphong,lvphophong;
 ArrayList<NhanVien>arrNvForTP=new ArrayList<NhanVien>();
 ArrayAdapter<NhanVien> adapterForTP;
 ArrayList<NhanVien>arrNvForPP=new ArrayList<NhanVien>();
 ArrayAdapter<NhanVien> adapterForPP;
 ImageButton btnApply;
 int lastChecked=-1;
 PhongBan pb=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_thiet_lap_truong_phong);
 getFormWidgets();
 }
 /**
 * hàm lấy control theo id
 * xử lý sự kiện checked (chọn chức vụ cho nhân viên)
 * Mọi thứ là hướng đối tượng nên nó tự tham chiếu
 */
 public void getFormWidgets()
 {
 lvtruongphong=(ListView) findViewById(R.id.lvtruongphong);
 lvtruongphong.setTextFilterEnabled(true);
 lvtruongphong.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
 lvtruongphong.setOnItemClickListener(new OnItemClickListener() {
 boolean somethingChecked = false;
 @Override
 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
 long arg3) {
 arrNvForTP.get(arg2).setChucvu(ChucVu.TruongPhong);
 if(somethingChecked){
 CheckedTextView cv = (CheckedTextView) arg1;
 cv.setChecked(false);

 }
 CheckedTextView cv = (CheckedTextView) arg1;
 if(!cv.isChecked())
 {
 cv.setChecked(true);
 arrNvForTP.get(arg2).setChucvu(ChucVu.TruongPhong);
 }
 else
 {
 arrNvForTP.get(arg2).setChucvu(ChucVu.NhanVien);
 }
 lastChecked = arg2;
 somethingChecked=true;
 }

 });
 lvphophong=(ListView) findViewById(R.id.lvphophong);
 lvphophong.setOnItemClickListener(new OnItemClickListener() {
 @Override
 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
 long arg3) {
 CheckedTextView cv = (CheckedTextView) arg1;
 if(!cv.isChecked())
 {cv.setChecked(true);
 arrNvForPP.get(arg2).setChucvu(ChucVu.PhoPhong);
 }
 else
 {cv.setChecked(false);
 arrNvForPP.get(arg2).setChucvu(ChucVu.NhanVien);
 }
 }

 });

 adapterForTP=new ArrayAdapter<NhanVien>(this,
 android.R.layout.simple_list_item_single_choice,
 arrNvForTP);
 adapterForPP=new ArrayAdapter<NhanVien>(this,
 android.R.layout.simple_list_item_multiple_choice,
 arrNvForPP);
 lvtruongphong.setAdapter(adapterForTP);
 lvphophong.setAdapter(adapterForPP);
 //Lấy được phòng ban gửi qua từ MainActivity
 Intent i= getIntent();
 Bundle bundle= i.getBundleExtra("DATA");
 pb= (PhongBan) bundle.getSerializable("PHONGBAN");
 addNvToListTP(pb);
 addNvToListPP(pb);
 adapterForTP.notifyDataSetChanged();
 adapterForPP.notifyDataSetChanged();

 btnApply=(ImageButton) findViewById(R.id.imgapply);
 btnApply.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View arg0) {
 doApply();

 }
 });
 }
 /**
 * gửi thông tin lại Mainactivity sau khi thiết lập
 */
 public void doApply()
 {
 Intent i=getIntent();
 Bundle bundle=new Bundle();
 bundle.putSerializable("PHONGBAN", pb);
 i.putExtra("DATA", bundle);
 setResult(MainActivity.THIET_LAP_TP_PP_THANHCONG, i);
 finish();
 }
 /**
 * duyệt toàn bộ nhân viên vào danh sách ứng viên Trưởng phòng
 * @param pb
 */
 public void addNvToListTP(PhongBan pb)
 {
 arrNvForTP.clear();
 for(NhanVien nv:pb.getListNhanVien())
 {
 arrNvForTP.add(nv);
 }
 }
 /**
 * duyệt toàn bộ nhân viên vào danh sách ứng viên phó phòng
 * @param pb
 */
 public void addNvToListPP(PhongBan pb)
 {
 arrNvForPP.clear();
 for(NhanVien nv:pb.getListNhanVien())
 {
 arrNvForPP.add(nv);
 }
 }
}

– Như vậy Tôi đã trình bày xong ví dụ 25.

– Bài tập này nó rất khó và phức tạp, bạn phải đọc đi đọc lại và làm đi làm lại

– Nếu như bài tập này bạn hiểu thì coi như bạn hiểu được phần lớn Intent và đã biết cách ứng dụng nó.

– Bạn tải coding mẫu toàn bộ tại đây:http://www.mediafire.com/?x8yyy2rewwcf9su

– Bài tập sau Tôi sẽ có thêm 1 ví dụ về implicit intent (cũng là intent). Mục đích của ví dụ này là Tôi viết chương trình gọi điện thoại và nhắn tin sms (không sử dụng chương trình có sẵn của Android).

– Bạn hãy chú ý theo dõi.

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


– Các bạn đã đi qua được các thành phần giao diện  trong Android, bài tập này các bạn sẽ làm quen với Intent. Intent rất quan trọng nó là linh hồn của Android, là hạt nhân để Android tồn tại, hầu như mọi thứ trong Android đều có dấu ấn của Intent.

– Các bạn cần hiểu rõ Intent, Tôi sẽ đưa ra hàng loạt ví dụ từ dễ tới khó để các bạn có thể thẩm thấu nó từ từ.

– Đối với người bắt đầu tiếp cận Android thì Tôi có thể nói rằng các bạn chỉ dùng Intent để mở các Activity và truyển dữ liệu qua lại giữa chúng mà thôi. Khi đã nâng cao level thì bạn sẽ sử dụng Intent ở những mục đích khác nhau (Tôi sẽ có những ví dụ riêng về nó, nhưng trước tiên các bạn chỉ cần sử dụng tốt trong việc mở Activity và xử lý tác vụ này tốt là ok rồi).

– Vì lý do đó , để phù hợp với các bạn thì Tôi chia Intent ra làm 2 công dụng chính:

1) Dùng Intent để mở một Activity khác nhưng không kiểm soát kết quả trả về.

2) Dùng Intent để mở một Activity khác và có kiểm soát kết quả trả về.

Bây giờ chúng ta vào từng ví dụ cụ thể:

Ví dụ 1: Đơn thuần là mở một Activity khác.

24_intent_0– Tôi giải thích hình trên như sau: Từ Main Activity Tôi có 1 Button, khi nhấn vào Button này thì sẽ mở một Activity khác, tại Activity mới mở này sẽ có 1 Button cho phép quay trở lại MainActivity.

– Bạn phải nhớ lại vòng đời của một ứng dụng Android ở bài tập 5bài tập 6 để làm ví dụ này tốt hơn.

– Bạn tạo một Android Project có cấu trúc như hình bên dưới:

24_intent_1– Bạn chú ý là mọi Activity muốn được triệu gọi trong Android thì phải đăng ký trong Manifest, ở các bài tập trước Tôi cũng đã nói rồi, nhưng Tôi vẫn nhắc lại AndroidManifest.xml:


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="tranduythanh.com"
 android:versionCode="1"
 android:versionName="1.0" >
 <uses-sdk
 android:minSdkVersion="14"
 android:targetSdkVersion="17" >
 </uses-sdk>
 <application
 android:allowBackup="true"
 android:icon="@drawable/ic_launcher"
 android:label="@string/app_name"
 android:theme="@style/AppTheme" >
 <activity
 android:name="tranduythanh.com.MainActivity"
 android:label="@string/app_name" >
 <intent-filter>
 <action android:name="android.intent.action.MAIN" />
 <category android:name="android.intent.category.LAUNCHER" />
 </intent-filter>
 </activity>
 <activity
 android:name="tranduythanh.com.ChildActivity"
 android:label="@string/title_activity_child" >
 </activity>
 </application>
</manifest>

– Bạn thấy đó cả MainActivity (dòng 16) và ChildActivity (Dòng 24)  đều phải được đăng ký trong Manifest.

– Giờ ta xem giao diện và cách xử lý coding trong MainActivity:

24_intent_2– Đây là cấu trúc XML của activity_main.xml ở trên:


<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="100dp"
 android:background="#008000"
 android:gravity="center"
 android:text="This is main Activity"
 android:textColor="#FFFF00"
 android:textSize="20sp"
 android:textStyle="bold" />

<Button
 android:id="@+id/btnOpenChildActivity"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:text="Open Child Activity" />

</LinearLayout>

– Tiến hành xem coding MainActivity.java:


package tranduythanh.com;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class MainActivity extends Activity {
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 Button btnOpen=(Button)
 findViewById(R.id.btnOpenChildActivity);
 btnOpen.setOnClickListener(new
 View.OnClickListener() {
 public void onClick(View arg0) {
 doOpenChildActivity();
 }
 });
 }
 public void doOpenChildActivity()
 {
 Intent myIntent=new Intent(this, ChildActivity.class);
 startActivity(myIntent);
 }
 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;
 }
}

– Quan sát dòng lệnh 25:

Intent myIntent=new Intent(this, ChildActivity.class);

Đối số 1 là context hiện tại, nếu bạn muốn chắc ăn ở đâu nó cũng hiểu thì bạn gán tên class Activity như thế này:

Intent myIntent=new Intent(MainActivity.thisChildActivity.class);

Với MainActivity là một Activity tùy ý (trong Context hiện tại), viết như trên thì bạn sẽ luôn luôn đúng trong mọi trường hợp.

Đối số 2 là :  ChildActivity.class, Tức là bạn muốn mở Activity nào thì lấy tên Activity đó .class; trong trường hợp này Tôi muốn mở ChildActivity nên Tôi ghi là ChildActivity.class

– Quan sát dòng lệnh 26
startActivity(myIntent); Hàm này có tác dụng mở Activity được truyền vào đối số thứ 2 ở trên.

– Tiến hành khám phá ChildActivity:

24_intent_3-Đầy là source XML của ChildActivity:


<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=".ChildActivity" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="match_parent"
 android:layout_height="100dp"
 android:background="#FFFF00"
 android:gravity="center"
 android:text="This is Child Activity"
 android:textColor="#008040"
 android:textSize="20sp"
 android:textStyle="bold" />

<Button
 android:id="@+id/btnBacktoMainActivity"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:text="Back to Main Activity" />

</LinearLayout>

-Giao diện của ChildActivity chỉ có một Button cho phép quay lại MainActivity.

– Bạn xem coding của ChildActivity:


package tranduythanh.com;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;

public class ChildActivity extends Activity {
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_child);
 Button btnBack= (Button)
 findViewById(R.id.btnBacktoMainActivity);
 btnBack.setOnClickListener(new
 View.OnClickListener() {
 public void onClick(View v) {
 finish();
 }
 });
 }
 public boolean onCreateOptionsMenu(Menu menu) {
 // Inflate the menu; this adds items to the action bar if it is present.
 getMenuInflater().inflate(R.menu.activity_child, menu);
 return true;
 }
}

-Dòng lệnh 18:  finish() có nhiệm vụ đóng Activity hiện tại.

– Bạn vừa đi qua 1 ví dụ vô cùng đơn giản.

– Tải coding ở đây:http://www.mediafire.com/?awoq5mkffm00qes

———————————————————————————-

Ví dụ 2: Mở một Activity khác đồng thời truyền dữ liệu qua.

– Bạn xem hình Tôi minh họa dưới này:

24_intent_4– Ở đây Ta thường dùng đối tượng Bundle để đóng gói dữ liệu để truyền tải qua các Activity khác.

– Tại sao lại nên dùng Bundle để truyền tải dữ liệu qua lại giữa các Activity?

+ Tối lấy ví dụ sau: Giả sử bạn phải chuyển toàn bộ hàng hóa từ Việt Nam sang Singapore, trường hợp này Ta sẽ bỏ tất cả các hàng hóa vào trong 1 Container rồi chuyển Container này đi, Không phải chuyển từng món hàng 1 qua Singapore. Tương tự như vậy, đối với Android khi truyền dữ liệu chúng ta cũng có thể truyền từng thông số riêng lẻ nhưng chúng ta không nên, chúng ta phải bỏ tất cả các dữ liệu riêng lẻ đó vào 1 Bundle rồi gửi Bundle này qua Activity nào đó. Bên kia chỉ cần lấy Bundle này ra, mọi dữ liệu đều nằm trong Bundle và ta dễ dàng xử lý.

24_intent_5– Bundle có 2 loại phương thức: putXXX dùng để cho bên gửi đi, ứng với kiểu dữ liệu nào thì put đúng kiểu đó. ở ví dụ trên putInt và putDouble là tương ứng với 2 loại dữ liệu khác nhau (phải đi kèm với key để bên nhận có thể xử lý đúng)

– Ở bên nhận Bundle thì dùng các phương thức getXXX tương ứng để lấy dữ liệu theo key bên gửi.

– key này phải giống nhau cho cả 2 nơi. Nơi nhận đặt key=soa thì bên nhận cũng phải dùng key=soa.

– Ta cũng có thể truyền Đối Tượng qua lại giữa các Activity, các đối tượng này phải được Serialize

24_intent_6– Trong trường hợp truyền đối tượng thì ta dùng putSerializable getSerializable

– Tôi sẽ làm một ví dụ đơn giản với giao diện như bên dưới:

24_intent_7– Từ MainActivity có 2 thông số là a và b. Khi nhấn nút Kết quả nó sẽ truyền 2 thông số này qua ResultActivity và tiến hành giải phương trình bậc 1. Muốn trở về để tiếp tục giải phương trình khác khi nhấn nút Back.

– Bạn xem cấu trúc chương trình để dễ xử lý:

24_intent_8– Bạn xem giao diện của MainActivity (activity_main.xml):

24_intent_9– Đây là Source XML của MainActivity:


<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:layout_gravity="center"
 android:background="#008040"
 android:gravity="center"
 android:text="Giải phương trình bậc 1"
 android:textColor="#FFFF00" />
 <TableLayout
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:stretchColumns="*"
 >
 <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:background="#E5E5E5"
 android:text="Nhập a:" />
 <EditText
 android:id="@+id/txta"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:inputType="text"
 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:background="#E5E5E5"
 android:text="Nhập b:" />
 <EditText
 android:id="@+id/txtb"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:inputType="text"
 android:ems="10" />
 </TableRow>
 <TableRow
 android:id="@+id/tableRow3"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 >
 <Button
 android:id="@+id/btnketqua"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_column="1"
 android:text="Kết quả" />
 </TableRow>
 </TableLayout>
</LinearLayout>

– Trong xml layout Bạn có thể chọn layout nào cũng được, ở trên Tôi dùng TableLayout

– Tiến hành xem coding của MainActivity.java:


package tranduythanh.com;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity {
 EditText txta,txtb;
 Button btnketqua;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 txta=(EditText) findViewById(R.id.txta);
 txtb=(EditText) findViewById(R.id.txtb);
 btnketqua=(Button) findViewById(R.id.btnketqua);
 btnketqua.setOnClickListener(new View.OnClickListener() {
 public void onClick(View arg0) {
 //Tạo Intent để mở ResultActivity
 Intent myIntent=new Intent(MainActivity.this, ResultActivity.class);
 //Khai báo Bundle
 Bundle bundle=new Bundle();
 int a=Integer.parseInt(txta.getText().toString());
 int b=Integer.parseInt(txtb.getText().toString());
 //đưa dữ liệu riêng lẻ vào Bundle
 bundle.putInt("soa", a);
 bundle.putInt("sob", b);
 //Đưa Bundle vào Intent
 myIntent.putExtra("MyPackage", bundle);
 //Mở Activity ResultActivity
 startActivity(myIntent);
 }
 });
 }
 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;
 }
}

– Tôi đã giải thích mã lệnh trong đoạn code ở trên rồi.

– Ở dòng 31, key nhận dạng Bundle là MyPackage, bên ResultActivity sẽ dựa vào key này để lấy Bundle ra.

– Sau khi có Bundle rồi thì dựa vào soa, sob ở dòng lệnh 28,29 để lấy đúng dữ liệu.

– Bây giờ ta qua giao diện ResultActivity:

24_intent_10– Bạn xem XML Resource của ResultActivity:


<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=".ResultActivity" >

<TextView
 android:id="@+id/textView1"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:gravity="center"
 android:text="Kết quả giải phương trình bậc 1" />

<TextView
 android:id="@+id/txtketqua"
 android:layout_width="match_parent"
 android:layout_height="50sp"
 android:gravity="center"
 android:background="#CCFFD9"
 />

<Button
 android:id="@+id/btnBack"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_gravity="center"
 android:text="Back" />

</LinearLayout>

– Tiếp tục xem xử lý coding của ResultActivity:


package tranduythanh.com;

import java.text.DecimalFormat;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class ResultActivity extends Activity {
 TextView txtketqua;
 Button btnBack;
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_result);
 btnBack=(Button) findViewById(R.id.btnBack);
 txtketqua=(TextView) findViewById(R.id.txtketqua);
 //lấy intent gọi Activity này
 Intent callerIntent=getIntent();
 //có intent rồi thì lấy Bundle dựa vào MyPackage
 Bundle packageFromCaller=
 callerIntent.getBundleExtra("MyPackage");
 //Có Bundle rồi thì lấy các thông số dựa vào soa, sob
 int a=packageFromCaller.getInt("soa");
 int b=packageFromCaller.getInt("sob");
 //tiến hành xử lý
 giaipt(a, b);
 btnBack.setOnClickListener(new View.OnClickListener() {
 public void onClick(View v) {
 finish();
 }
 });
 }
 public void giaipt(int a,int b)
 {
 String kq="";
 if(a==0 && b==0)
 {
 kq="Vô số nghiệm";
 }
 else if(a==0 && b!=0)
 {
 kq="Vô nghiệm";
 }
 else
 {
 DecimalFormat dcf=new DecimalFormat("0.##");
 kq=dcf.format(-b*1.0/a);
 }
 txtketqua.setText(kq);
 }
 @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_result, menu);
 return true;
 }
}

-Bạn xem dòng lệnh 22: Intent callerIntent=getIntent(); lệnh này cho phép lấy Intent start Activity này. Tức là lấy Intent mà ta khai báo bên MainActivity để start ResultActivity.

– Có được Intent này rồi thì mọi thứ bạn làm như  Tôi giải thích trong Coding ở trên.

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

———————————————————————————-

Ví dụ 3: Mở một Activity khác đồng thời truyền dữ liệu qua và xử lý kết quả trả về.

– Ví dụ này bạn sẽ biết cách xử lý kết quả trả về như thế nào.

– Bạn xem hình minh họa:

24_intent_11– Chúng ta sẽ dựa vào requestCodeID và resultCode để xử lý.

– Việc tạo Intent trong trường hợp này cũng y xì như trường hợp trước. Nó chỉ khác hàm gọi :

24_intent_12– Và phải thêm hàm xử lý kết quả trả về:

24_intent_13– Tôi làm ví dụ sau để bạn dễ hiểu:

– Chương trình đơn giản là MainActivity sẽ có 1 Button và ListView như hình bên dưới:

24_intent_14– Khi nhấn “Mở Activity nhập dữ liệu”, chương trình sẽ mở Activity mới dưới dạng Dialog:

24_intent_15– Khi nhập số và nhấn “Lưu bình phương” thì nó sẽ truyền số này qua MainActivity và cập nhật ListView với số này là nhân bình phương.

– Khi nhập số và nhấn “lưu số gốc” thì nó sẽ truyền số này qua MainActivity và cập nhật ListView với đúng số gốc này.

– Bạn chú ý là phải đóng Dialog ngay, vì nếu không đóng thì onActivityResult sẽ không sảy ra. onActivityResult chỉ sảy ra trong foreground life time.

– Ta tiến hành khám phá ứng dụng:

– Xem cấu trúc chương trình:

24_intent_16– Source XML của Mainactivity:


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

<Button
 android:id="@+id/btnopenactivity"
 android:layout_width="match_parent"
 android:layout_height="wrap_content"
 android:text="Mở Activity Nhập Dữ Liệu" />

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

</LinearLayout>

– Source XML của activity_input_data.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=".InputDataActivity" >

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

<TextView
 android:id="@+id/textView1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Nhập số:" />

<EditText
 android:id="@+id/editNumber"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_weight="1"
 android:ems="10" >

<requestFocus />
 </EditText>

</LinearLayout>

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

<Button
 android:id="@+id/btnSave1"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_weight="1"
 android:text="Lưu Bình Phương" />

<Button
 android:id="@+id/btnSave2"
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_weight="1"
 android:text="Lưu Số gốc" />

</LinearLayout>

</LinearLayout>

– Nhớ là phải cấu hình InputDataActivity dưới dạng Dialog: Mở Manifest để cấu hình như hình bên dưới:

24_intent_17– chọn Theme: @android:style/Theme.Holo.Dialog

-Tại màn hình trên ta chọn đúng Activity muốn làm Dialog rồi tìm tới thuộc tính Theme, nhấn vào nút “Browse”…:

24_intent_18-Bây giờ bạn xem xử lý code của MainActivity.java:


package tranduythanh.com;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

public class MainActivity extends Activity {

public static final int REQUEST_CODE_INPUT=113;
 public static final int RESULT_CODE_SAVE1=115;
 public static final int RESULT_CODE_SAVE2=116;
 Button btnInputData;
 ListView lvData;
 ArrayList<Integer>arrData=new ArrayList<Integer>();
 ArrayAdapter<Integer>adapter=null;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 btnInputData =(Button) findViewById(R.id.btnopenactivity);
 btnInputData.setOnClickListener(new OnClickListener() {

@Override
 public void onClick(View arg0) {
 //Mở Activity với REQUEST_CODE_INPUT
 Intent intent=new Intent(MainActivity.this, InputDataActivity.class);
 //gọi startActivityForResult
 startActivityForResult(intent, REQUEST_CODE_INPUT);
 }
 });
 //đoạn code dưới này học nhiều rồi, ko nói lại
 lvData=(ListView) findViewById(R.id.lvdata);
 adapter=new ArrayAdapter<Integer>
 (this,
 android.R.layout.simple_list_item_1,
 arrData);
 lvData.setAdapter(adapter);
 }
 /**
 * Xử lý kết quả trả về ở đây
 */
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 // TODO Auto-generated method stub
 super.onActivityResult(requestCode, resultCode, data);
 //Kiểm tra có đúng requestCode =REQUEST_CODE_INPUT hay không
 //Vì ta có thể mở Activity với những RequestCode khác nhau
 if(requestCode==REQUEST_CODE_INPUT)
 {
 //Kiểm trả ResultCode trả về, cái này ở bên InputDataActivity truyền về
 //có nó rồi thì xử lý trở lên thông thường
 switch(resultCode)
 {
 case RESULT_CODE_SAVE1:
 //giá trị từ InputDataActivity
 int v1= data.getIntExtra("data", 0);
 arrData.add(v1*v1);
 adapter.notifyDataSetChanged();
 break;
 case RESULT_CODE_SAVE2:
 //giá trị từ InputDataActivity
 int v2= data.getIntExtra("data", 0);
 arrData.add(v2);
 adapter.notifyDataSetChanged();
 break;
 }
 }
 }
 @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úng ta nên khai báo hằng số cho RequestCode và ResultCode như ở trên, dựa vào nó để chúng ta xử lý kết quả trả về.

– Bạn qua xử lý code của InputDataActivity.java:


package tranduythanh.com;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class InputDataActivity extends Activity {

Button btnSave1,btnSave2;
 EditText editNumber;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_input_data);
 btnSave1=(Button) findViewById(R.id.btnSave1);
 btnSave2=(Button) findViewById(R.id.btnSave2);
 btnSave1.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View arg0) {
 //Gửi thông điệp là lưu bình phương
 sendToMain(MainActivity.RESULT_CODE_SAVE1);
 }
 });
 editNumber=(EditText) findViewById(R.id.editNumber);
 btnSave2.setOnClickListener(new OnClickListener() {

 @Override
 public void onClick(View v) {
 //Gửi thông điệp là lưu số gốc
 sendToMain(MainActivity.RESULT_CODE_SAVE2);
 }
 });
 }
 /**
 * hàm xử lý gửi kết quả về mainactivity
 * khi hàm này được gọi thì lập tức onActivityResult
 * ở MainActivity sẽ sảy ra đem theo ResultCode và Intent
 * @param resultcode
 */
 public void sendToMain(int resultcode)
 {
 Intent intent=getIntent();
 int value= Integer.parseInt(editNumber.getText()+"");
 intent.putExtra("data", value);
 setResult(resultcode, intent);
 finish();
 }
 @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_input_data, menu);
 return true;
 }

}

– Bạn nhìn vào hàm sendToMain, khi hàm này vừa kết thúc thì lập tập onActivityResult của MainActivity sẽ sảy ra

onActivityResult(int requestCode, int resultCode, Intent data)

Ta kiểm tra requestCode và resultCode cho đúng

requestCode là bên MainActivity dùng để triệu gọi một Activity bất kỳ nào đó

resultCode là kết quả trả về trong hàm setResult(resultcode, intent); của sub Activity nào đó. Hàm này cho chúng ta biết kết quả trả về là code nào và đồng thời cho ta biết luôn Intent của nó. Dựa vào Intent này mà trong onActivityResult ta có thể dễ dàng lấy thông số ra (đối số thứ 3).

– Như vậy bạn đã biết sơ qua về Intent, bạn phải lại đi làm lại 3 ví dụ của Tôi vừa nêu ra bên trên.

– Trong bài tập tiếp theo, Tôi sẽ củng cố kiến thức Intent cho bạn bằng một ví dụ cụ thể đầy đủ và hơi khó về Intent, bạn hãy chú ý theo dõi.

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

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