Android onClick in XML so với OnClickListener


86

Tôi nhận ra rằng một câu hỏi có từ tương tự đã được hỏi trước đây, nhưng điều này khác. Tôi còn khá mới trong việc phát triển các ứng dụng android và tôi có ba câu hỏi liên quan đến (các) sự khác biệt giữa android:onclick=""thuộc tính XML và setOnClickListenerphương thức.

  1. Đâu là sự khác biệt giữa cả hai? Sự khác biệt giữa hai triển khai có được tìm thấy tại thời gian biên dịch hoặc thời gian chạy hay cả hai không?

  2. Những trường hợp sử dụng nào là thuận lợi cho việc thực hiện?

  3. Việc sử dụng các phân đoạn trong Android có gì khác biệt trong việc lựa chọn triển khai?


1
Đối với # 2: Bạn nên cẩn thận khi sử dụng xml onclickvì bạn cần đảm bảo rằng mọi lớp đều triển khai phương thức đó. Điều này giả định rằng bạn đang sử dụng bố cục nhiều lần. Tuy nhiên, nếu bạn có một giao diện java để đảm bảo phương thức nằm trong tất cả các lớp đã triển khai nó, bạn sẽ không phải lo lắng.
Uxonith

Việc có một giao diện java như bạn đã mô tả sẽ không giống với việc mở rộng hoặc thêm vào OnClickListener?
KG6ZVP

Tôi đã xem xét vấn đề này trước đây và tôi nghĩ rằng có nhiều thứ hơn một chút so với sở thích, nhưng tôi xin lỗi vì tôi không thể nói nhiều hơn vì đã lâu rồi. Tôi giống như android:onclickkhi nó thuận tiện, nhưng tôi biết rằng đôi khi nó đã gây ra vấn đề này, và tôi không thể nhớ những hai :)
Uxonith

xml onClick không làm việc cho các yếu tố bố trí lồng nhau được tự động phồng lên ở mức API 19
Amit Kaushik

1
Tôi hiếm khi thấy mã từ những người khác triển khai android: onClick và đó là điều khó hiểu nhất khi bạn xem qua mã của ai đó. Vì nó không có tất cả các khả năng của setOnClickListener nên gần như mọi người chỉ sử dụng setOnClickListener theo ý kiến ​​của tôi
Christian

Câu trả lời:


122

Sự khác biệt giữa OnClickListener và OnClick:

  • OnClickListener là giao diện bạn cần triển khai và có thể được đặt thành chế độ xem trong mã java.
  • OnClickListener là thứ chờ ai đó thực sự nhấp vào, onclick xác định điều gì sẽ xảy ra khi ai đó nhấp vào.
  • Gần đây, android đã thêm thuộc tính xml vào các chế độ xem được gọi là android: onclick, có thể được sử dụng để xử lý các nhấp chuột trực tiếp trong hoạt động của chế độ xem mà không cần triển khai bất kỳ giao diện nào.
  • Bạn có thể dễ dàng hoán đổi việc triển khai một trình nghe này với một trình nghe khác nếu bạn cần.
  • OnClickListener cho phép bạn tách hành động / hành vi của sự kiện nhấp chuột khỏi Chế độ xem kích hoạt sự kiện. Trong khi đối với các trường hợp đơn giản, đây không phải là vấn đề lớn, đối với việc xử lý sự kiện phức tạp, điều này có nghĩa là khả năng đọc và bảo trì mã tốt hơn
  • Vì OnClickListener là một giao diện, lớp triển khai nó có khả năng linh hoạt trong việc xác định các biến cá thể và phương thức mà nó cần để xử lý sự kiện. Một lần nữa, đây không phải là vấn đề lớn trong các trường hợp đơn giản, nhưng đối với các trường hợp phức tạp, chúng tôi không muốn trộn lẫn các biến / phương thức liên quan đến xử lý sự kiện với mã của Chế độ xem kích hoạt sự kiện.
  • OnClick với liên kết hàm trong Bố cục XML là ràng buộc giữa onClick và hàm mà nó sẽ gọi. Hàm phải có một đối số (Chế độ xem) để onClick hoạt động.

Cả hai đều hoạt động theo cùng một cách, chỉ là một cái được đặt thông qua mã java và cái kia thông qua mã xml.

Triển khai mã setOnClickListener:

Button btn = (Button) findViewById(R.id.mybutton);

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    myFancyMethod(v);
    }
});

// some more code

public void myFancyMethod(View v) {
    // does something very interesting
}

Triển khai XML:

<?xml version="1.0" encoding="utf-8"?>
<!-- layout elements -->
<Button android:id="@+id/mybutton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click me!"
    android:onClick="myFancyMethod" />
<!-- even more layout elements -->

Hiệu suất:

Cả hai đều giống nhau về hiệu suất. Xml được phân tích trước thành mã nhị phân trong khi biên dịch. vì vậy không có quá đầu trong Xml.

Giới hạn:

android: onClick dành cho API cấp 4 trở đi, vì vậy nếu bạn đang nhắm mục tiêu <1.6, thì bạn không thể sử dụng nó.


`Xml được phân tích trước thành mã nhị phân trong khi biên dịch` Câu lệnh này chính xác có nghĩa là gì? Vì tôi đã thấy mã dexcode của một apk có android: onClick trong tệp kê khai của nó, nhưng tôi không tìm thấy bất kỳ mã nào đặt trình nghe
VicX

lời giải thích tuyệt vời. +1
Zia Ur Rahman

1
Trên thực tế, có một số chi phí trong XML . Khi nút được nhấp lần đầu tiên, phản xạ được sử dụng để xác định phương thức sẽ được gọi . Tuy nhiên, điều này có lẽ là không đáng kể đối với hầu hết các trường hợp sử dụng (và tối ưu hóa quá sớm là căn nguyên của mọi điều xấu xa).
Yoel

21

Tôi rất ngạc nhiên là không ai nói về điều này nhưng hãy cẩn thận, mặc dù android:onClickXML có vẻ là một cách thuận tiện để xử lý nhấp chuột, nhưng setOnClickListenerviệc triển khai thực hiện một số việc bổ sung hơn là thêm onClickListener. Thật vậy, nó đặt thuộc tính xemclickable thành true.

Mặc dù nó có thể không phải là vấn đề trên hầu hết các triển khai Android, nhưng theo hàm tạo của điện thoại, nút luôn được mặc định thành clickable = true nhưng các hàm tạo khác trên một số kiểu điện thoại có thể có mặc định clickable = false trên các chế độ xem không phải Nút.

Vì vậy, thiết lập XML là không đủ, bạn phải suy nghĩ mọi lúc để thêm android:clickable="true"vào nút non, và nếu bạn có một thiết bị mà mặc định là clickable = true và bạn quên đặt thuộc tính XML này thậm chí một lần, bạn sẽ không nhận thấy vấn đề trong thời gian chạy nhưng sẽ nhận được phản hồi trên thị trường khi nó sẽ đến tay khách hàng của bạn!

Ngoài ra, chúng ta không bao giờ có thể chắc chắn về cách proguard sẽ xáo trộn và đổi tên các thuộc tính XML và phương thức lớp, vì vậy không an toàn 100% rằng chúng sẽ không bao giờ có lỗi một ngày nào đó.

Vì vậy, nếu bạn không bao giờ muốn gặp rắc rối và không bao giờ nghĩ về nó, tốt hơn là sử dụng setOnClickListenerhoặc các thư viện như ButterKnife với chú thích@OnClick(R.id.button)


1
Bạn có kinh nghiệm nào (hoặc đã thấy ở đâu đó) lỗi xảy ra do quá trình xáo trộn khi sử dụng android:onClickkhông?
Akram

Cảm ơn ngài! Câu trả lời của bạn rất hữu ích!
Yi Shen

12

Đơn giản:

Nếu bạn có android:onClick = "someMethod" trong xml , nó sẽ tìm kiếm public void someMethodtrong lớp Hoạt động của bạn. OnClickListenerđược gọi ngay từ Hoạt động của bạn và nó được liên kết với một số cụ thể View. Ví dụsomeButton.setOnClickListener và trong đoạn mã dưới đây cho biết những gì phải được thực hiện khisomeButton được nhấn.

Hy vọng nó giúp :)


4

Như đã nói trước đây: cả hai đều là một cách để thêm logic để phản hồi một sự kiện, trong trường hợp này là một sự kiện 'nhấp chuột'.

Tôi muốn tách biệt giữa logic và bản trình bày, giống như chúng ta làm trong thế giới HTML / JavaScript: Để lại XML cho bản trình bày và thêm trình xử lý sự kiện bằng mã.


1
Đồng ý, trừ khi đó là một ứng dụng rất nhỏ với một số hành vi đơn giản, tất cả các mã thực thi của bạn nên được giữ riêng biệt và được tổ chức tốt, tốt nhất là sử dụng phương pháp riêng biệt
OzzyTheGiant

0

Nếu bạn có nhiều nút chỉ sử dụng một phương pháp, tôi khuyên bạn nên làm điều đó trong java. Nhưng nếu bạn có một nút với một phương thức cụ thể, onClick trong XML sẽ tốt hơn.


0

Sẽ thuận tiện hơn khi luôn sử dụng thuộc tính android: onClick trừ khi bạn có lý do chính đáng để không làm như vậy, ví dụ: nếu bạn khởi tạo Nút trong thời gian chạy hoặc bạn cần khai báo hành vi nhấp trong lớp con Fragment.


3
Tôi hiếm khi thấy mã từ những người khác triển khai android: onClick và đó là điều khó hiểu nhất khi bạn xem qua mã của ai đó. Vì nó không có tất cả các khả năng của setOnClickListener nên gần như mọi người chỉ sử dụng setOnClickListener theo ý kiến ​​của tôi
Christian

0

Có một số lý do tại sao bạn có thể muốn đặt một OnClickListener. Đầu tiên là nếu bạn muốn thay đổi hành vi của nút khi ứng dụng của bạn đang chạy. Bạn có thể trỏ nút của mình đến một phương pháp khác hoàn toàn hoặc chỉ cần vô hiệu hóa nút bằng cách đặt một phương pháp OnClickListenerkhông làm gì cả.

Khi bạn xác định một trình lắng nghe bằng cách sử dụng onClickthuộc tính, dạng xem chỉ tìm kiếm một phương thức có tên đó trong hoạt động máy chủ của nó. Cài đặt theo chương trình OnClickListenercho phép bạn kiểm soát hành vi của một nút từ một nơi khác ngoài hoạt động trên máy chủ của nó. Điều này sẽ trở nên rất phù hợp khi chúng tôi sử dụng Fragments, về cơ bản là các hoạt động nhỏ, cho phép bạn xây dựng các bộ sưu tập chế độ xem có thể tái sử dụng với vòng đời của chúng, sau đó có thể được tập hợp thành các hoạt động. Các phân đoạn luôn cần sử dụng OnClickListenersđể điều khiển các nút của chúng, vì chúng không phải là Hoạt động và sẽ không được tìm kiếm cho các trình nghe được xác định trong onClick.


-2

Tôi nghĩ sự khác biệt chính giữa chúng là:

OnClick: Khi bạn dùng ngón tay bấm vào nút.

OnClickListner: Nó có thể là một sự lựa chọn rộng rãi hơn được triển khai trong nhiều mã khác nhau.

Ví dụ: khi bạn nhập url "ymail.com", yahoo sẽ tìm thấy tên người dùng và mật khẩu của bạn từ trình duyệt của bạn và bật nút trạng thái nhấp để mở thư của bạn. Hành động này chỉ nên được triển khai trong onClickListener.

Đây là ý tưởng của tôi!


Điều này thật thú vị nhưng còn nhiều điều hơn thế nữa; của bạn nên có một bình luận.
Dakatine
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.