Tuesday 26 August 2014

Chuyển từ Activity này sang Activity khác và nhận dữ liệu trả về

Từ đầu tutorial đến giờ mình và các bạn cũng đã đi qua khá nhiều khái niệm quan  trọng nhưu Intent hay Layout. Tiếp tục quay trở về vấn đề Intent trong bài này mình sẽ hướng dẫn các bạn chuyển Activity và get dữ liệu trả về tự một Activity. Giả sử bạn có một activity và bạn muốn lấy thông thông tin trả về từ activity thứ 2 sau khi bạn từ activity 1 đi tới activity2. Vậy làm sao để thực hiện việc này, dưới đây sẽ là hướng dẫn giúp các bạn :)
Đầu tiên tạo một New Project Android có tên là ChangeActivityAndGetInfor
Sau khi tạo xong project các bạn hãy tạo tiếp một new Activity, chắc các bạn vẫn có nhớ cách tạo new Activity mà mình đã hướng dẫn không thì các bạn có thể đọc ở bài Những công cụ cần thiết cho việc lập trình Android
Tiếp đó các bạn hãy mở file layout của activity vừa tạo. Ở đây mình tạo một new Activity có tên là InformationActivity ở trong file layout của nó là activity_information.xml mình sẽ tạo một form gồm các trường name, age và một button OK với nội dung như sau


<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="${relativePackage}.${activityClass}" >

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

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

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:text="User Name" />

            <EditText
                android:id="@+id/txtUserName"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:focusableInTouchMode="true"
                android:inputType="text"
                android:minWidth="200dp"
                android:hint="Enter Name" />
        </TableRow>

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

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:text="Age" />

            <EditText
                android:id="@+id/txtAge"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginLeft="10dp"
                android:focusableInTouchMode="true"
                android:inputType="number"
                android:minWidth="200dp"
                android:hint="Enter Age(Number)" />
        </TableRow>
    </TableLayout>

    <Button
        android:id="@+id/bntOk"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="100dp"
        android:text="OK" />


</RelativeLayout>

Sau khi tạo xong giao diện của nó sẽ là



Hãy để ý đoạn code chúng ta vừa tạo ra có một vài điểm mình muốn lưu ý với các bạn. Giả sử với EditText là name
 android:inputType="number"
 android:minWidth="200dp"
 android:hint="Enter Age(Number)"
Khi các bạn muốn EditText có validate tức bạn chỉ muốn nhập là số, text hay email các bạn có thể dùng thuộc tính là inputType. minWidth là độ rộng tối thiểu, nếu bạn đã làm việc với css trong html thì nó cũng tương tự như vậy, tiếp theo là thuộc tính android:hint nó giống như một text hướng dẫn người dùng khi bạn nhập text vào thì nó sẽ tự động biến mất, tương tự thuộc tính placeholder của EditText của trong html. Ngoài ra nó còn khá nhiều thuộc tính hay các bạn hãy tìm hiểu thêm.

Trong file java của activity này InformationActivity.java source code như sau

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

public class InformationActivity extends Activity {

private EditText txtName;
private EditText txtAge;
private Button btnOK;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_information);
this.txtName = (EditText) findViewById(R.id.txtUserName);
        this.txtAge = (EditText) findViewById(R.id.txtAge);
        this.btnOK = (Button) findViewById(R.id.bntOk);
        
        this.btnOK.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
String name = txtName.getText().toString();
String age = txtAge.getText().toString();

Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("NAME", name);
bundle.putString("AGE", age);
intent.putExtra("RESULT_DATA", bundle);
//intent.setData(Uri.parse(name + age));get and setData
//intent.setAction("RETURN_INFOR_INFORMATION");
setResult(RESULT_OK, intent);

finish();
}
});
}
}

OK nhìn có vẻ rắc rối đúng không nhưng bạn hãy quan tâm vào việc bắt sự kiện cho button. Đầu tiên chúng ta sẽ getText() trong 2 ô EditText, tiếp đó chúng ta tạo một new Intent và một new Bundle. Mình xin giới thiệu qua Bundle là một đối tượng dùng để chứa dữ liệu trong Android bằng cách đặt vào các giá trị theo cặp Key/value. Để đặt giá trị các bạn dùng putXXXX. còn muốn lấy dữ liệu các bạn dùng getXXXX theo KEY. Trong những đoạn sắp tới các bạn thấy sẽ thấy việc làm này. Tiếp tục các bạn đặt dữ liệu là name và age vừa get được và truyền vào. Để Intent mang được dữ liệu các bạn cần put đối tượng vào Intent ở đây là
intent.putExtra("RESULT_DATA", bundle); cũng theo dạng Key/value OK. Tiếp tục chúng ta cần setResult(RESULT_OK, intent);  Để đảm bảo rằng việc lấy dữ liệu và trả về là đúng và gọi hàm kết thúc Activity bạn đang thao tác điều này giúp leak memory, giúp chương trình tối ưu bộ nhớ hơn. khi đó máy ảo sẽ thu hồi bộ nhớ giúp các bạn.

Quay trở lại file main_activity.xml với nội dung như sau

<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.example.changeactivityandgetinfor.MainActivity" >

    <Button
        android:id="@+id/btnChangeActivity"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="87dp"
        android:text="Go Sencond Activity" />

</RelativeLayout>



Đơn giản chúng ta chỉ cần tạo một button với nhiệm vụ chuyển tới activity vừa rồi là InfomationActivity.

Trong file MainActivity.java với nội dung như sau
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;


public class MainActivity extends Activity {

private final int REQUEST_CODE = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btnChangeActivity = (Button) findViewById(R.id.btnChangeActivity);
        btnChangeActivity.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this, InformationActivity.class);
startActivityForResult(intent, REQUEST_CODE);
}
});
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // TODO Auto-generated method stub
    super.onActivityResult(requestCode, resultCode, data);
    System.out.println("Get data");
    if (requestCode == this.REQUEST_CODE) {
    if (resultCode == RESULT_OK) {
    //String dataReturn = data.getDataString(); //get and setData
    Bundle bundle = data.getBundleExtra("RESULT_DATA");
    if (bundle != null) {
    String name = bundle.getString("NAME");
    String age = bundle.getString("AGE");
    //Show ket qua tra ve
    Toast.makeText(this, "Name: " + name + "\nAge: " + age, Toast.LENGTH_SHORT).show();
    } else {
    System.out.println("Bundle null");
    }
    }
    }
    }

Các bạn cần chú ý khi các chúng ta muốn chuyển activity và muốn lấy dữ liệu từ activity chuyển tới trả về các bạn cần sử dụng, startActivityForResult và cần override lại phương thức onActivityResult. Ở đây
mình sẽ giải thích chi tiết. khi sử dụng chúng ta cần một biến gọi là REQUEST_CODE tức là mã yêu cầu, hãy giả sử như mỗi sinh viên vào trong trường cần phải có mã số thể để kiếm soát thì ở đây cũng vậy, mỗi công việc khác nhau khi các bạn sử dụng startActivityForResult thì cần tạo ra request code khác nhau để phân biệt khi mà giá trị trả về được get thông qua phương thức onActivityResult. Giả sử như
 if (requestCode == REQUEST_CODE_1) {
     //do to something
} else if(requestCode == REQUEST_CODE_2) {
//do to something
}
Tiếp tục chúng ta cần so sánh nếu việc trả về với requestCode là hợp lệ cũng nhưng resultCode == RESULT_OK thì chúng ta tiếp tục get dữ liệu được Intent mang theo. Bạn có nhớ trước đó chúng ta đã sử Bundle để chứa dữ liệu thì ở đây chúng ta cũng sử bundle để get lại dữ liệu theo Key tương ứng. Nếu làm thực tế thì bạn nên đặt các key là các hằng số kiểu String để chúng ta dễ thao tác cũng như sáng sủa hơn.
Nếu bunle khác NULL thì cúng ta get và show dữ liệu lên bằng đối tượng Toast trong Android mình sẽ giới thiệu sau nhưng nó cũng rất là đơn giản. Trước đó mình có nhắc tới setData và getData ở đoạn code trên mình đã comment để các bạn thấy điều này.

OK bật máy ảo lên và chúng ta chạy thử chương trình chúng ta được
Đầu tiên hãy nhập input


Nhấn button OK và kết quả trả về


Hy vọng các bạn đã hiểu cách để chúng ta get dữ liệu từ một Activity. Ngoài ra chúng ta còn có thể chuyển dữ liệu khi từ Activity một sang Activity hai. Đơn giản chúng ta cũng chỉ set và get dữ liệu nhưng nó hơi khác một chút nhưng xử lý dễ dàng hơn so với cách mà chúng ta đang thực hiện. Mình sẽ làm rõ vấn đề này ở những loạt bài tiếp theo.







1 comment :

  1. bạn cho mình xin source code đc không, mình đã làm theo ở trên nhưng ko đc @@

    ReplyDelete