Android 里面自定义监听器我没搞明白. 监听器是能够做到每时每刻监听是吗? 那像这些自己写出来的监听器究竟是怎么做到监听的?
像这个Android 帮助文档上的实现 dialog 的代码(代码如下), 自己编的一个 interface 被 MainActivity 继承为什么就能做到监听? — NoticeDialogListener
为什么能够接收到点击按钮的事件呢?
以下是上述文档的代码. 当然我问的也不仅仅是这个代码了… 谢谢回答!
For example, here's a DialogFragment that defines an interface through
which it delivers the events back to the host activity:public class NoticeDialogFragment extends DialogFragment { /* The activity that creates an instance of this dialog fragment must * implement this interface in order to receive event callbacks. * Each method passes the DialogFragment in case the host needs to query it. */ public interface NoticeDialogListener { public void onDialogPositiveClick(DialogFragment dialog); public void onDialogNegativeClick(DialogFragment dialog); } // Use this instance of the interface to deliver action events NoticeDialogListener mListener; // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener @Override public void onAttach(Activity activity) { super.onAttach(activity); // Verify that the host activity implements the callback interface try { // Instantiate the NoticeDialogListener so we can send events to the host mListener = (NoticeDialogListener) activity; } catch (ClassCastException e) { // The activity doesn't implement the interface, throw exception throw new ClassCastException(activity.toString() + " must implement NoticeDialogListener"); } } ... }
The activity hosting the dialog creates an instance of the dialog with
the dialog fragment's constructor and receives the dialog's events
through an implementation of the NoticeDialogListener interface:public class MainActivity extends FragmentActivity implements NoticeDialogFragment.NoticeDialogListener{ ... public void showNoticeDialog() { // Create an instance of the dialog fragment and show it DialogFragment dialog = new NoticeDialogFragment(); dialog.show(getSupportFragmentManager(), "NoticeDialogFragment"); } // The dialog fragment receives a reference to this Activity through the // Fragment.onAttach() callback, which it uses to call the following methods // defined by the NoticeDialogFragment.NoticeDialogListener interface @Override public void onDialogPositiveClick(DialogFragment dialog) { // User touched the dialog's positive button ... } @Override public void onDialogNegativeClick(DialogFragment dialog) { // User touched the dialog's negative button ... } }
Because the host activity implements the NoticeDialogListener—which is enforced by the onAttach() callback
method shown above—the dialog fragment can use the interface callback
methods to deliver click events to the activity:public class NoticeDialogFragment extends DialogFragment { ... @Override public Dialog onCreateDialog(Bundle savedInstanceState) { // Build the dialog and set up the button click handlers AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); builder.setMessage(R.string.dialog_fire_missiles) .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the positive button event back to the host activity mListener.onDialogPositiveClick(NoticeDialogFragment.this); } }) .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { // Send the negative button event back to the host activity mListener.onDialogNegativeClick(NoticeDialogFragment.this); } }); return builder.create(); } }
이것은 본질적으로 메소드 호출입니다. 두 개의 클래스 A와 B가 있고 A에서 특정 순간에 B의 메서드를 호출할 것으로 예상한다고 가정합니다. A가 B에 대한 참조를 유지하고 적절한 시간에 메서드를 호출하도록 할 수 있습니다.
으아악위 코드는 A에서 특정 순간(무슨 일이 발생했을 때)에 B에게 무엇인가를 하라고 알리는 간단한 청취 모드입니다. 보시다시피, B는 A의 행동을 항상 모니터링하는 것이 아니라 A가 특정 순간에 B의 방법을 적극적으로 트리거합니다.
여기서 B를 Listener로 바꾸면 친숙한 청취자가 됩니다.
따라서 B의 하위 클래스를 작성하고 사용자 정의 리스너를 구현할 수 있습니다.
으아악디자인 패턴 측면에서 "조합은 많이 사용하고 상속은 적게 사용"이라는 권장 접근 방식이 있는데, 이는 위의 B를 인터페이스로 변경해 보겠습니다.
으아악그런 다음 이전에 상속된 구현을 인터페이스 구현으로 바꿉니다.
으아악보시다시피 사용법은 이전과 똑같습니다.
인터페이스 B를 OnClickListener 인터페이스로 바꾸면 훨씬 더 명확해질까요? 이를 디자인 패턴에서는
观察者模式
이라고 합니다.책 추천: "Head First Design Pattern", 처음 두 장은 위에서 언급한
策略模式
과观察者模式
을 소개합니다.듣는 사람을 말 그대로 이해하지 못하고, 시간이 발생하는지 적극적으로 확인하지 않기 때문에 매 순간 그런 것이 없습니다.
우리에게 Android의 Listener는 실제로 콜백 메서드인 콜백일 뿐입니다. 이벤트 발생시 이벤트 개시자나 내부 핸들러가 호출하는 메소드입니다.
직접 작성한 Listener 클래스는 등등을 상속받기 때문에 이벤트를 들을 수 있는 것이 아니라, 이벤트 발생 시 지정된 메서드가 이벤트의 개시자나 내부 핸들러에게 알려줄 수 있는 방법을 찾기 위해 작성되었습니다. 이 리스너를 호출해야 합니다. 이것은 또한 일반적으로 수행되는 setListener 프로세스입니다.
이 논리는 귀하가 제공한 코드에서 매우 명확하게 추론되었습니다. 먼저 코드를 주의 깊게 살펴보시기 바랍니다.
이것은 바로 리스너라고 불리는 디자인 패턴입니다. 능동적으로 실행되는 것이 아니라 수동적으로 실행됩니다. 이 패턴을 이해하고 나면 직접 작성할 수 있습니다. 이것이 바로 우리가 콜백이라고 부르는 것입니다.
Java의 Listener는 콜백 함수를 지정하는 인터페이스입니다. Listener의 구현 클래스(일반적으로 익명 내부 클래스)는 콜백 함수 객체 자체입니다. Java에서 함수 객체(클로저라고도 함)를 전달하려면 이 작업을 수행해야 합니다.
저도 오래 전 Java를 배울 때 반 친구들에게 이런 질문을 한 적이 있습니다. 당신이 입양한 사람은 이것이 본질적으로 메소드 호출이라는 것을 이미 분명히 밝혔습니다.
사실 수업 시간에 잘 듣고 수업 후에 선생님이 작성한 코드를 주의 깊게 입력하면 문제를 이해할 수 있을 것입니다.
확실한 것은 저는 항상 문제를 미루고 해결하는 것을 좋아한다는 것입니다. 나중에는 불가능합니다.
하루에 700줄 이상으로 더 많은 코드를 작성하는 것이 좋습니다.
입력할 코드가 없다고 생각하시나요? 다른 사람들이 알아낸 질문을 할 때는 코드를 세 번이나 입력해야 합니다. 입력할 코드가 없다면 의미 있는 작은 프로그램을 몇 개만 입력하면 됩니다.
코딩을 고수한다는 것은 처음부터 튼튼하다는 것을 의미합니다.