Lắng nghe sự kiện cho Button trong lập trình Android


Từ: 09:00 20/09/2014
Bài: 10
Cảm ơn: 2
Thích: 3

Có nhiều cách để “bắt” sự kiện click vào 1 button trong lập trình android, tùy từng trường hợp cụ thể để ta lựa chọn cách viết thích hợp nhất.

Trong tut này tôi sử dụng IDE là Eclipse.

Tạo 1 project Android application với file giao diện chính là activity_main.xml, activity chính là MainActivity.java, dưới đây là các cách để lắng nghe sự kiện cho 1 button:

  1. Inline Listener

Trong giao diện chúng t thêm 1 button với các thuộc tính như sau:

    <Button

        android:id="@+id/button1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:onClick="myEvent"

        android:text="ClickMe!" />

 

Trong đó android:onClick="myEvent" để đăng ký phương thức sẽ xử lý khi button1 được click.

Trong file MainActivity.java chúng ta xây dựng 1 phương thức có tên myEvent và truyền cho phương thức này 1 View

     public void myEvent(View view) {

           // Xử lý khi button được click

           Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_LONG)

                     .show();

     }

Khi đó: nếu button1 được click thì phương thức myView sẽ được gọi.

2. Inline Anonymous Listener

Vẫn với button như trên nhưng ta bỏ thuộc tính android:onClick="myEvent"

Khi  đó để xử lý được sự kiện khi ta click vào button1,  trong file MainActivity.java trong phương thức onCreate ta cần đăng ký sự kiện click cho button1

     @Override

     protected void onCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState);

           setContentView(R.layout.activity_main);

           Button btn_clickme = (Button) findViewById(R.id.button1);

           btn_clickme.setOnClickListener(new View.OnClickListener() {

               

                @Override

                public void onClick(View arg0) {

                     // Xử lý khi button được click

                     Toast.makeText(MainActivity.this, "Button clicked!",

                                Toast.LENGTH_LONG).show();

                }

           });

     }

 

3. Activity is Listener

- Trong cách viết sự kiện này thì Activity sẽ implements interface có kiểu sự kiện (rất nhiều loại interface). Ở đây Tôi chỉ ví dụ trường hợp cho Button các trường hợp khác các bạn tự tìm hiểu và suy luận ra.

File xml vẫn như ví dụ 2.

public class MainActivity extends Activity implements OnClickListener {

 

     @Override

     protected void onCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState);

           setContentView(R.layout.activity_main);

           Button btn_clickme = (Button) findViewById(R.id.button1);

           btn_clickme.setOnClickListener(this);

     }

 

     @Override

     public void onClick(View arg0) {

           // Xử lý khi button được click

           Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_LONG)

                     .show();

          

     }

}

4. Listener is Variable

      - Tương tự như Activity Is listener, nhưng  khác ở chỗ thay vì implement interface cho Activity thì nó lại được lưu trữ vào một biến có kiểu Listener trong activity. Làm cách này thì ta có thể chia sẻ chung một biến sự kiện cho các control khác nhau.

 

     @Override

     protected void onCreate(Bundle savedInstanceState) {

           super.onCreate(savedInstanceState);

           setContentView(R.layout.activity_main);

           OnClickListener myListener = new OnClickListener() {

               

                @Override

                public void onClick(View arg0) {

                     // TODO Auto-generated method stub

                     Toast.makeText(MainActivity.this, "Button clicked!", Toast.LENGTH_LONG)

                     .show();

                }

           };

           Button btn_clickme = (Button) findViewById(R.id.button1);

           btn_clickme.setOnClickListener(myListener);

  }

 

 

5. Explicit listener class

Trường hợp này ta tách riêng một class đóng vai trò là class sự kiện riêng.

- Khi nào lượng coding trong ứng dụng khổng lồ và phức tạp thì ta nên tách class sự kiện riêng để dễ quản lý.

public class MainActivity extends Activity {

 

   @Override

   protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        Button btn_clickme = (Button) findViewById(R.id.button1);

        btn_clickme.setOnClickListener(new myListener());

   }

 

   private class myListener implements OnClickListener {

        @Override

        public void onClick(View arg0) {

             // TODO Auto-generated method stub

             Toast.makeText(MainActivity.this, "Button is clicked!",

                        Toast.LENGTH_SHORT).show();

        }

   }

}

.

Label
Từ: 15:10 16/10/2013
Bài: 10
Cảm ơn: 4
Thích: 0

Mấy cách đăng ký sự kiện này có ưu nhược điểm hay trường hợp sử dụng cụ thể gì không bạn?

Bạn thường hay dùng cách nào vậy?

Label
Từ: 09:00 20/09/2014
Bài: 10
Cảm ơn: 2
Thích: 3

@duytung các cách đăng ký trên đều có ưu và nhược điểm riêng, ví dụ như cách 1: bạn đang ký sự kiện trong file xml, như thế nếu b có nhiều đối tượng cần xử lý sự kiện thì b sẽ rất khó để quản lý được chúng, chính vì vậy cách 1 chỉ dùng cho trường hợp có 1 - 2 sự kiện cần xử lý.

Tôi thường sử dụng cách 2-Inline Anonymous Listener, như vậy t sẽ tạo 1 phương thức chỉ để đăng ký sự kiện cho các đối tượng, và trong đó t gọi vào các công việc cần xử lý. Cách số 5 cũng rất hay được sử dụng: t tách riêng từng công việc ra từng class( mỗi class nằm trên 1 file java riêng) từ đó dễ dàng quản lý được code của m.
Label
Từ: 10:39 21/09/2012
Bài: 33
Cảm ơn: 30
Thích: 10

Tiện thể cho mình hỏi: Mình có một form có các Button thêm, sửa xóa.

Các button này đều có sự kiện Click. Bạn sẽ chọn cách nào để đăng ký onClick cho button? Mình thấy với mỗi button mà lại .setOnClick thì rườm rà quá

Label
Từ: 09:00 20/09/2014
Bài: 10
Cảm ơn: 2
Thích: 3

@dongtaiit trong trường hợp này, theo m bạn nên sử dụng cách 3  "Activity implements OnClickListener",  hoặc cách số 5 - Viết 1 class để xử lý các sự kiện cho 3 button.

Như vậy trong phương thức    "public void onClick(View arg0){}",  b có thể bắt được nút nào đang được "click" bằng cách lấy ra id của View truyền vào(arg0.getID()), so sánh với id từng button, m thường dùng switch-case để xử lý trong trường hợp này :).

Nhưng chắc chắn mỗi button vẫn cần được thiết đặt hành động nào sẽ được gọi khi có sự kiện, ví dụ: btn_edit.setOnClickListener(this);//cho cách 3, hoặc btn_edit.setOnClickListener(new your_class_listener);// cho cách số 5 .

Mọi người cùng nhận xét!
Label
Từ: 10:39 21/09/2012
Bài: 33
Cảm ơn: 30
Thích: 10

Đang nghĩ không biết so sánh getID() với cái gì :v

Cái khó ló cái khôn, Khai báo btn có phạm vi toàn cục rồi so sánh luôn arg0 với  btn_x tương ứng với cách xử lý sự kiện khác nhau :D

Label
Từ: 15:10 16/10/2013
Bài: 10
Cảm ơn: 4
Thích: 0

Em thấy với .NET có 2 phần (phần giao diện và phần xử lý riêng), phải chăng theo như cách 5 thì có phần giống với cách xử lý của .NET. Không biết có phải không ạ?

Label
Từ: 09:00 20/09/2014
Bài: 10
Cảm ơn: 2
Thích: 3

@dongtaiit ,  nếu ta gọi getID() rồi so sánh với ID của mỗi button (R.id.btn_x) là 1 hướng, nhưng nếu t có nhiều giao diện (file xml) thì việc ta gọi ID như vậy sẽ dễ bị nhầm lẫn, nếu ta khai báo btn_x là biến toàn cục cho toàn class thì "có mà chạy đằng trời" :)

@duytung  bạn nói đúng, nhưng không chỉ có .NET mà hầu như tất cả ngôn ngữ lập trình đều hướng tới "kiểu" lập trình như vậy - chuyên biệt hóa từng công việc.
Label
Từ: 16:25 24/09/2014
Bài: 2
Cảm ơn: 0
Thích: 1

Tùy vào số lượng sự kiện chứng ta xây dựng cho ứng dụng mà chọn

 Khoảng  dăm ba sự kiện thi viết sự kiện onClick trong file XML hoặc viết ngày sự kiện trong lúc thiết lập nắng nghe sự kiện cho control

Vừa khoảng tầm 10 sự kiện đổ lại thi implements OnClickListene code cho dễ, nhìn cũng sáng xủa
Nhiều thì làm cái class để xử lý riêng, vừa tiên ,lại vừa chuyên nghiệp