Thiết kế giao diện và xử lý sự kiện trong Android Studio 3.6 (trở lên)

Android framework duy trì một hàng đợi chứa các sự kiện khi chúng xuất hiện. Để xử lý các sự kiện, Android dùng các trình lắng nghe sự kiện (event listeners) để lắng nghe các sự kiện và dùng phương thức callback tương ứng để xử lý các sự kiện đó. Ví dụ để xử lý sự kiện Click của một Button chúng ta cần đăng ký sự kiện này đến trình lắng nghe sự kiện View.onClickListener và gọi phương thức callback onClick tương ứng. Đoạn mã Java minh họa cho việc lắng nghe và xử lý sự kiện:


// tạo một đối tượng Button

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

//đăng kí sự kiện đến trình lắng nghe View.onClickListener

button.setOnClickListener(new View.OnClickListener() {

    // thực thi phương thức callback onClick

    public void onClick(View v) {

            // nội dung thực thi

    }

});

Một cách khác là chúng ta thực thi phương thức callback onClick ngay tại phần tử XML tương ứng của view bằng cách sử dụng thuộc tính android:onClick. Ví dụ đối với Button Infomation trong ứng dụng BasicViews:


<Button
       android:id="@+id/btnInfo"
       android:text="@string/btnInfo"
       android:onClick="info"
...
/>

info trong đoạn mã trên là phương thức chứa mã thực thi được khai báo trong lớp Activity chứa button Information. Phương thức info có một số đặc điểm chung cho tất cả các phương thức dùng trong thuộc tính android:onClick là:

  • Phải là phương thức có phạm vi public
  • Trả về void
  • Có đối tượng View là tham số

Trong ứng dụng BasicViews chúng ta sẽ viết hai phương thức trong lớp BasicViewsActivity (trong tập tin BasicViewsActivity.java) là phương thức cancel() cho Button Cancel và phương thức info() cho Button Information. Lớp BasicViewsActivity với hai phương thức cancel() và info() như sau:


public class BasicViewsActivity extends AppCompatActivity {

      @Override
      protected void onCreate(Bundle savedInstanceState) {
             super.onCreate(savedInstanceState);
             setContentView(R.layout.activity_basic_views;
       }

       public void cancel(View v){
              System.exit(0);
       }

       public void info(View v){
              AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
              dlgAlert.setMessage("Hello World! I am Ngoc Minh.");
              dlgAlert.setTitle("My First App");
              dlgAlert.setPositiveButton("OK", null);
              dlgAlert.setCancelable(true);
              dlgAlert.create().show();
       }
}

chúng ta đang sử dụng lớp AlertDialog nên cần import lớp đó vào tập tin BasicViewsActivity.java:


import android.app.AlertDialog;

Cách nhanh nhất để xử lý sự kiện Click của hai button Cancel (ID: btnCancel) và button Information (ID: btnInfo) là gọi phương thức callback onClick tại các thuộc tính XML của hai button. Mã tập tin activity_basic_views.xml cho hai button như sau:


<Button
      android:id="@+id/btnCancel"
      android:text="@string/btnCancel"
      android:onClick="cancel"
.../>

<Button
      android:id="@+id/btnInfo"
      android:text="@string/btnInfo"
      android:onClick="info"
.../>

Lưu ý rằng, hai phương thức cancel và info khai báo trong lớp BasicViewsActivity phải có phạm vi là public.

Chúng ta cũng có thể xử lý sự kiện Click theo cách thứ hai với 3 bước:

Bước 1: khai báo các đối tượng button tham chiếu đến hai button Cancel và Information trong phương thức onCreate:


Button btnCancel =  (Button)findViewById(R.id.btnCancel);
Button btnInfo =  (Button)findViewById(R.id.btnInfo);

Bước 2: đăng ký sự kiện Click của mỗi button đến trình lắng nghe View.onClickListener và gọi phương thức callback onClick tương ứng:


btnCancel.setOnClickListener(new View.OnClickListener() {
    // thực thi phương thức callback onClick
    public void onClick(View v) {
        // nội dung thực thi
    }
});

btnInfo.setOnClickListener(new View.OnClickListener() {
     // thực thi phương thức callback onClick
     public void onClick(View v) {
          // nội dung thực thi
     }
});

Bước 3: viết mã thực thi cho các phương thức onClick (cụ thể là gọi các phương thức cancel() và info()):


btnCancel.setOnClickListener(new View.OnClickListener() {
    // thực thi phương thức callback onClick
    public void onClick(View v) {
         // nội dung thực thi
        cancel(v);
     }
});
btnInfo.setOnClickListener(new View.OnClickListener() {
   // thực thi phương thức callback onClick
   public void onClick(View v) {
       // nội dung thực thi
       info(v);
   }
});

Bây giờ chúng ta thực thi chương trình và nhấn button Information:

Nếu nhấn button Cancel sẽ đóng chương trình.

Kế tiếp, chúng ta sẽ lấy thông tin từ các views. Tạo các đối tượng và tham chiếu đến các views tương tứng trong giao diện bằng phương thức findViewById trong phương thức onCreate:


Button btnCancel =  (Button)findViewById(R.id.btnCancel);
Button btnInfo =  (Button)findViewById(R.id.btnInfo);
final EditText editName =  (EditText)findViewById(R.id.editName);
final EditText editEmail =  (EditText)findViewById(R.id.editEmail);
final CheckBox chkCoding =  (CheckBox) findViewById(R.id.chkCoding);
final CheckBox chkReading =  (CheckBox) findViewById(R.id.chkReading);
final CheckBox chkTravelling =  (CheckBox) findViewById(R.id.chkTravelling);
final RadioButton rdMale =  (RadioButton) findViewById(R.id.rdMale);
final RadioButton rdFemale =  (RadioButton) findViewById(R.id.rdFemale);
final Spinner spinLang =  (Spinner) findViewById(R.id.spinLang);
final Switch switchExpert =  (Switch) findViewById(R.id.switchExpert);

Chúng ta có thể thiết lập và lấy dữ liệu từ Name và Email bằng cách dùng các phương thức setText() và getText() của các đối tượng editName và editEmail, nhưng trước đó chúng ta cần điều chỉnh phương thức info như sau:


public void info(View v, String msg){
        AlertDialog.Builder dlgAlert = new AlertDialog.Builder(this);
        dlgAlert.setMessage(msg);
        dlgAlert.setTitle("My First App");
        dlgAlert.setPositiveButton("OK", null);
        dlgAlert.setCancelable(true);
        dlgAlert.create().show();
}

trong phương thức onClick của button Information:


    String msg = "My name: " + editName.getText().toString() +
                  System.getProperty("line.separator") +
                 "Email: " + editEmail.getText().toString();
    info(v,msg);

Chúng ta cần nội dung các ô Name và Email phải rỗng sau khi nhấn nút Information. Có thể thực hiện điều này bằng cách gọi phương thức setText() của hai đối tượng editName và editEmail trong:


   String msg = "My name: " + editName.getText().toString() +
                System.getProperty("line.separator") +
                "Email: " + editEmail.getText().toString();
   info(v,msg);
   editName.setText("");
   editEmail.setText("");

Thực thi ứng dụng:

Nhấn button Information:

 

Để lấy giá trị từ các checkbox khi chúng được chọn bởi người dùng chúng ta sẽ kiểm tra xem một checkbox đã được chọn hay chưa và nếu được chọn thì chúng ta sẽ lấy giá trị của checkbox bằng phương thức getText():


if(chkCoding.isChecked())
        msg +=  chkCoding.getText().toString()+ ", ";
if(chkReading.isChecked())
        msg += chkReading.getText().toString() + ", ";
if(chkTravelling.isChecked())
        msg += chkTravelling.getText().toString()+ ", ";

Có thể thiết lập trạng thái được chọn (true) hay chưa được chọn (false) cho các checkbox bằng phương thức setChecked(), ví dụ:


chkCoding.setChecked(false);
chkReading.setChecked(false);
chkTravelling.setChecked(false);

Chạy ứng dụng:

Nhấn button Information:

Để lấy giá trị từ các RadioButton chúng ta cũng thực hiện tương tự CheckBox. Điểm khác biệt là mỗi lần chúng ta chỉ có thể chọn một RadioButton (trong cùng một RadioGroup):


if(rdFemale.isChecked())
     msg += rdFemale.getText().toString();
if(rdMale.isChecked())
     msg += rdMale.getText().toString();

Có thể thiết lập trạng thái được chọn (true) hay chưa được chọn (false) cho các radiobutton bằng phương thức setChecked(), ví dụ:


rdFemale.setChecked(false);
rdMale.setChecked(false);

Chạy ứng dụng:

Nhấn nút Information:

Để lấy giá trị được chọn từ Spinner chúng ta dùng phương thức getSelectedItem():


msg += System.getProperty("line.separator") + "My language: " + 
       spinLang.getSelectedItem().toString();

Kiểm tra một Switch được chọn hay chưa:


if(switchExpert.isChecked())
    msg += "Yes";
else
    msg += "No";

Thực thi chương trình:

Nhấn button Information:

Mã nguồn hoàn chỉnh của BasicViews có thể xem tại GitHub.