Cơ bản về Activity
Một Activity bạn tạo ra bằng cách kế thừa (extends) lớp android.app.Activity (hoặc lớp AppCompatActivity, ta sẽ dùng cách này, xem chú thích phần dưới) mà khi kích hoạt nó sẽ tạo ra một cửa sổ nơi chúng ta sẽ chèn giao diện (UI) vào bằng phương thức setContentView(View)Như trình bày trong vòng đời Activity Android có một số giai đoạn. Để Activity hoạt động hoạt động tối thiểu bạn cần nạp chồng (overrided) phương thức onCreate(Bundle), nó là phương thức được gọi ở giai đoạn đầu tiên của chu kỳ vòng đời Activity, chính vì thể đây là chỗ mà chúng ta sẽ nạp giao diện cho nó bằng phương thức setContentView(int) hoặc setContentView(View)
Bạn cũng có thể cần nạp chồng phương thức onPause(), phương thức này gọi khi Activity chuyển sang trạng thái tạm dừng tức là lúc giao diện của nó không còn xuất hiện nữa (ví dụ khi kích hoạt một Activity khác, Activity khác nó hoạt động và che hết màn hình), code trong phương thức này thường để lưu lại các thông tin (vì Acvitity có thể không được kích hoạt lại)
Ví dụ tạo một Acvitity tên là:
Lession2Activity
public class Lession2Activity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lession2_activity); //Các khởi tạo khác nếu cần thiết } @Override protected void onPause() { super.onPause(); //Code to save data } }Trong đoạn code trên có setContentView(R.layout.lession2_activity); thì đã yêu cầu nạp UI có tên là lession2_activity, vậy ta cần tạo UI này, nó tương ứng với file
res/layout/lession2_activity.xml
, ví dụ tạo ra mẫu đơn giản gồm có một TextView hiện thị một đoạn văn, và
một nút bấm Button:<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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" xmlns:app="http://schemas.android.com/apk/res-auto"> <TextView android:id="@+id/noidung" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:background="#2aab1194" android:padding="5dp" android:text="Đây là một đoạn văn trong View của layout: lession2_activiy. Lập trình Android bài 2." app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/editbutton" android:text="Edit" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/textView" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" /> </android.support.constraint.ConstraintLayout>Trong phần Layout này, ngoài phần tử gốc là ConstraintLayout, có sử dụng phần tử là TextView và gán một chỉ số ID cho nó tên là noidung với cú pháp thuộc tính android:id="@+id/noidung" và phần tử Button có gán ID là editbutton
Để gán id cho các View ở file xml, dùng cú pháp: android:id="@+id/tên_id". Giá trị của chỉ số đó tự động phát sinh
bởi SDK, muốn lấy giá trị đó dùng cú pháp R.id.tên_id
Khi mà Activity Lession2Activity
nạp xong layout bởi hàm setContentView(int) thì nó đã tạo ra đối tượng lớp TextView, Button thông số mô tả trong layout.
Để lấy được đối tượng này ở phần code Java dùng lệnh findViewById(int), bạn có thể cập nhật lại onCreate ở trên như sau để lấy được hai đối tượng View trên.@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lession2_activity); TextView textView = findViewById(R.id.noidung); Button edibutton = findViewById(R.id.editbutton); }
Để tìm ra View theo id, dùng phương thức findViewById(id_của_view), nó sẽ tìm trên toàn bộ giao diện nạp vào cho Active, nếu thấy View nó
sẽ trả về đối tượng View, nếu không trả về null
Bắt sự kiện khi bấm vào ViewTất cả các View đều có khả năng lắng nghe các sự kiện chạm / vuốt trên màn hình, nếu muốn View nào đó bắt sự kiện click (bấm + nhả nhanh) thì sử dụng phương thức setOnClickListener(listener) của View, trong đó listener là đối tượng lớp View.OnClickListener (nạp chồng phương thức onClick(View view) là phương thức gọi khi có sự kiện xảy ra)
Ví dụ sửa lại
onCreate
để bắt sự kiện khi bấm vào nút editbutton, khi bấm vào thì hiện dòng chữ thông báo Vừa bấm vào Edit@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lession2_activity); TextView textView = findViewById(R.id.noidung); Button edibutton = findViewById(R.id.editbutton); //Tạo listener cho sự kiện Click View.OnClickListener listenerEditbutton = new View.OnClickListener() { @Override public void onClick(View view) { Toast.makeText(view.getContext(), "Vừa bấm vào Edit", Toast.LENGTH_SHORT).show(); } }; //Gán Listener cho editbutton edibutton.setOnClickListener(listenerEditbutton); }
Để popup một box nhỏ hiện thị thông báo thì dùng Toast.makeText(context,thongbao,Toast.LENGTH_SHORT).show();
trong đó context là đối tượng Context, Active là một Context, nếu là View thì lấy Context của nó bằng View.getContext(), thongbao là dòng chữ String hoặc CharSequence
Cấu hình Activity trong AndroidManifest.xmlĐể một Activity có thể mở ra được (chạy được) bằng phương thức Context.startActivity(); hoặc khởi chạy khi mở ứng dụng thì phải khai báo nó trong
AndroidManifest.xml
.Mỗi Activity khai báo trong manifest đều nằm trong phần tử application với cú pháp
<!-- .... --!> <activity android:name="lớp_Activity"> <!-- các tham số con --!> </activity> <!-- .... --!>Ngoài thuộc tính android:name như trên, tùy thuộc mục đích còn có nhiều thuộc tính khác kế thừa từ Theme, hoặc được thiết lập trực tiếp như: android:screenOrientation, android:label, android:icon, android:permission ... (xem thêm Activity Manifest)
Để thiết lập Activity là Activity mặc định (chạy đầu tiên khi mở ứng dụng thì thêm
intent-filter
như sau vào trong phần
tử activity đó, ví dụ:<!-- .... --!> <activity android:name="lớp_Activity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- .... --!>Chạy thử:
Một số điều cơ bản cho phần này liên quan đến Activity
- Để tạo ra một Activity thì cần tạo lớp kế thừa từ
Activity
(android.app.Activity),AppCompatActivity
(android.support.v7.app.AppCompatActivity) nhưng nên triển khai từAppCompatActivity
vì đây cũng chính là một lớp kế thừa từ lớp Activity nhưng nó định nghĩa trong Support Libary, thư viện này hỗ trọ nhiều tính năng hiện đại chạy được trên Android Version cũ (tương thích ngược) - Activity phải nạp chồng phương thức onCreate(), và để chèn giao diện vào Activity thì trong onCreate gọi phương thức
setContentView(R.layout.tên_layout);
- Để tìm một View trong Activity dùng phương thức
findViewById(id_của_view);
- Trong quá trình lập trình cho Android, để lấy được các thành phần tài nguyên từ ID, layout ... phải dùng đến đối tượng Context, các Activity chính là một Context vì
nó thực ra mở rộng từ Context, trong các View lấy Context bằng phương thức
View.getContext()
Sử dụng Intent để chạy Activity
Chúng ta đều biết hệ điều hành Android được thiết kế cho các thiết bị cầm tay như điện thoại thông minh, máy tính bảng, đồng hồ thông minh ... đặc điểm chung của các thiết bị này so với Desktop, Laptop ... đó là tài nguyên hệ thống thấp hơn nhiều như bộ nhớ ít hơn, tốc độ CPU chậm hơn ... nên Android có có cơ chế để đảm bảo các tài nguyên đó được quản lý và thu hồi hợp lý nhất.Một trong các cơ chế đó là việc quản lý các Activity ứng dụng, khi giao diện của Activity không còn xuất hiện trên màn hình nó chuyển sang chế độ Pause, và Android có thể hủy Activity đó bất kể lúc nào nếu cần để thu hồi tài nguyên, thứ hai là giữa các Activity không bao giờ truy cập trực tiếp với nhau (Activity này không thể gọi phương thức, hay truy cập dữ liệu của Activity khác).
Do giữa các Activity không được liên lạc trực tiếp với nhau, nên để từ Activity này chạy một Activity khác, trao đổi dữ liệu giữa các Activity phải dùng tới một đối tượng có tên là Intent
Intent có nhiều mục đích, ở đây chỉ thảo luận việc dùng nó để từ một Activity này mở ra một Activity khác, dùng nó để gửi dữ liệu trả về. Giả sử có một Activity tên lớp là UpdateActivity, để từ một Activity nào đó mở được UpdateActivity thì tạo ra một đối tượng Intent thiết lập tham số phù hợp rồi gọi startActivity(intent) để gửi yêu cầu và dữ liệu mô tả trong Intent cho hệ thống Android, và hệ thống kích hoạt Activity phù hợp
Code khởi chạy Activity thông thường
Intent intent = new Intent(); //Gán context và tên lớp Activity cần chạy intent.setClass(view.getContext(), UpdateActivity.class); //Nếu có truyền tham số cho Activity intent.putExtra("dulieu1", 345); intent.putExtra("dulieu2", "Một chuỗi ..."); //Gửi Intent cho hệ thống Android để kích hoạt Activity startActivity(intent); //Muốn Activity thứ nhất kết thúc thì thêm finish();Khi hệ thống Android tạo ra Activity thứ 2 (UpdateActivity) thì nó cũng bắt đầu bằng hàm onCreate(); Trong hàm này có thể lấy tham số Actvity thứ nhất truyền qua bằng cách truy cập vào đối tượng Intent của Activity thứ 2, lấy Intent chứa dữ liệu bằng phương thức getIntent();, Có Intent rồi thì chỉ việc đọc dữ liệu bằng các phương thức tương ứng với kiểu dữ liệu theo tên như: intent.getStringExtra("tendulieu"); intent.getIntExtra("tendulieu", 0); ...
Ví dụ đọc dữ liệu trong onCreate
Intent intent = getIntent(); int dulieu1 = intent.getIntExtra("dulieu1", 0); String dulieu2 = intent.getStringExtra("dulieu2");Thực hành thiết kế UpdateActivity
UpdateActivity mục đích có chức năng để cập nhật nội dụng văn bản, nó mở ra khi bấm vào nút
Edit
trên Lession2Activityres\layout\update_activity.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout 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=".UpdateActivity" xmlns:app="http://schemas.android.com/apk/res-auto"> <EditText android:id="@+id/noidung_edit" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:layout_marginTop="8dp" android:lines="10" android:padding="5dp" android:gravity="top" android:background="#e8e5ea" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/ok_button" android:text="Save" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintTop_toBottomOf="@+id/noidung_edit" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" /> </android.support.constraint.ConstraintLayout>
UpdateActivity.java
package net.xuanthulab.firstapp; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class UpdateActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.update_activity); EditText noidung_edit = findViewById(R.id.noidung_edit); Intent intent = getIntent(); String noidung = intent.getStringExtra("noidung"); noidung_edit.setText(noidung); Button ok_button = findViewById(R.id.ok_button); //Băt sự kiện khi bấm nút Save ok_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { finish(); //Kết thúc Activity (sẽ quay trở về Activiy trước nó) Toast.makeText(view.getContext(), "Save", Toast.LENGTH_SHORT).show(); } }); } }Thêm vào
manifest
bên trong phần tử application
mô tả về UpdateActivity<activity android:name=".UpdateActivity" android:label="Edit content"/>Trong onCreate của Lession2Activity thêm vào đoạn mã để khi bấm vào nút Edit sẽ mở UpdateActivity
Button edibutton = findViewById(R.id.editbutton); //Tạo listener cho sự kiện Click View.OnClickListener listenerEditbutton = new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); //Gán context và tên lớp Activity cần chạy intent.setClass(view.getContext(), UpdateActivity.class); //Nếu có truyền tham số cho Activity intent.putExtra("noidung", textView.getText()); //Gửi Intent cho hệ thống Android để kích hoạt Activity startActivity(intent); //Muốn Activity thứ nhất kết thúc thì thêm finish(); } }; //Gán Listener cho editbutton edibutton.setOnClickListener(listenerEditbutton);Chạy ứng dụng:
Sử dụng Intent chứa kết quả trả về
Trong
UpdateActivity
nếu muốn nó trả kết quả về thì trước khi finish();
cần tạo một đối tượng Intent, rồi chuyển dữ liệu cần trả về vào đó như cách ở trên, cuối cùng
gọi phương thức setResult(code_result, data);
Bằng cách như vậy thì ở Activity khác có thể nhận được dữ liệu trả về từ
UpdateActivity
(chú ý các code trên,
mặc dù UpdateActivity có trả về dữ liệu thì Lession2Activity
vẫn chưa nhận được dữ liệu, ta cần chỉnh sửa một chút)Áp dụng cập nhật code cho
UpdateActivity
sẽ trả về dữ liệu có chứa dòng Text mới cập nhật lại.package net.xuanthulab.firstapp; import android.content.Intent; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; /** * Created by XUANTHULAB.NET on 15-Mar-18. */ public class UpdateActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.update_activity); EditText noidung_edit = findViewById(R.id.noidung_edit); Intent intent = getIntent(); String noidung = intent.getStringExtra("noidung"); noidung_edit.setText(noidung); Button ok_button = findViewById(R.id.ok_button); ok_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { setResultData(); finish(); Toast.makeText(view.getContext(), "Save", Toast.LENGTH_SHORT).show(); } }); } private void setResultData() { Intent data = new Intent(); EditText editText = findViewById(R.id.noidung_edit); String noidung = editText.getText().toString(); data.putExtra("noidung", noidung); int code_result = 1; setResult(code_result, data); } }
Nhận kết quả trả về từ một Activity khác
Ở phần trước, chúng ta sử dụng phương thức startActivity để khởi động Activity, nếu vậy thì nó
không nhận được kết quả trả về. Nếu muốn nhận kết quả trả về thì khởi động Activity bằng phương thức
startActivityForResult(Intent intent, int requestCode), trong đó requestCode
là một số nguyên
để bạn kiểm tra xem kết quả nhận về từ Activity nào.Nếu gọi như trên, thì Activity sẽ nhận dữ liệu thông qua phương thức onActivityResult, bạn chỉ việc nạp chồng hàm này và lấy dữ liệu trả về.
Cập nhật lại code Lession2Activity.java để nhận dữ liệu trả về và cập nhật lại vào TextView
public class Lession2Activity extends AppCompatActivity { final int RESULT_UPDATE_ACTIVITY = 1; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.lession2_activity); final TextView textView = findViewById(R.id.noidung); Button edibutton = findViewById(R.id.editbutton); //Tạo listener cho sự kiện Click View.OnClickListener listenerEditbutton = new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(); //Gán context và tên lớp Activity cần chạy intent.setClass(view.getContext(), UpdateActivity.class); //Nếu có truyền tham số cho Activity intent.putExtra("noidung", textView.getText()); //Gửi Intent cho hệ thống Android để kích hoạt Activity startActivityForResult(intent, RESULT_UPDATE_ACTIVITY); //Muốn Activity thứ nhất kết thúc thì thêm finish(); } }; //Gán Listener cho editbutton edibutton.setOnClickListener(listenerEditbutton); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case RESULT_UPDATE_ACTIVITY: String noidung = data.getStringExtra("noidung"); TextView textView = findViewById(R.id.noidung); textView.setText(noidung); break; default: break; } } @Override protected void onPause() { super.onPause(); //Code to save data } }Chạy ứng dụng:
Ta thấy kết quả trả về từ Activity thứ 2 nhận được bởi Activity thứ nhất.
Không có nhận xét nào :
Đăng nhận xét