java - 自己写的 interface 为什么能作为监听器?
大家讲道理
大家讲道理 2017-04-18 09:53:29
0
5
408

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();
    } 
}
大家讲道理
大家讲道理

光阴似箭催人老,日月如移越少年。

全員に返信(5)
迷茫

これは本質的にメソッド呼び出しです。 2 つのクラス A と B があり、A の特定の時点で B のメソッドを呼び出すことが期待されているとします。A に B への参照を保持させ、適切な時点でメソッド呼び出しを行うことができます。

リーリー

上記のコードは、A のある瞬間 (何かが起こったとき) に B に何かを行うように通知します。これは単純なリスニング モードです。ここでは、B が A のアクションを常に監視しているのではなく、A がある瞬間に B のメソッドを積極的にトリガーしています。

ここで、B を Listener に置き換えると、おなじみのリスナーになります。

B のサブクラスを作成し、カスタム リスナーを実装できます。

リーリー

デザイン パターンに関しては、「より多くの組み合わせを使用し、継承を減らす」という推奨アプローチがあります。これは、より多くのインターフェイスを使用し、より少ない継承を使用する必要があることを意味します。

の B をインターフェイスに変更しましょう。 リーリー

次に、以前に継承した実装をインターフェイスの実装に置き換えます。

リーリー

ご覧のとおり、使い方は以前とまったく同じです。

インターフェイス B を OnClickListener インターフェイスに置き換えると、よりわかりやすくなりますか?これをデザインパターンでは观察者模式と呼びます。

お勧めの本: 『Head First Design Pattern』。最初の 2 章では、上で述べた 策略模式观察者模式 を紹介します。

いいねを押す +0
迷茫

リスナーを文字通り理解することはできません。時間が発生したかどうかを積極的に確認するわけではないため、すべての瞬間というものは存在しません。
私たちにとって、Android のリスナーは実際には一種のコールバック、つまりコールバック メソッドにすぎません。イベント発生時にイベントイニシエーターまたは内部ハンドラーによって呼び出されるメソッドです。
私が書いた Listener クラスは、誰々から継承しているためイベントをリッスンすることができませんが、イベントが発生したときに指定されたメソッドが実行されることをイベントのイニシエーターまたは内部ハンドラーに伝える方法を見つけることを目的としています。この中でListenerを呼び出す必要があります。これも通常行われるsetListenerの処理です。

このロジックは、あなたが指定したコードで非常に明確に推定されています。まずコードを注意深く見てください。

いいねを押す +0
大家讲道理

これはリスナーと呼ばれるデザイン パターンであり、アクティブにトリガーされるのではなく、パッシブにトリガーされます。このパターンを理解すると、通常コールバックと呼ばれるものを自分で作成できます。

いいねを押す +0
阿神

Java のリスナーは、コールバック関数を指定するインターフェースです。 Listener の実装クラス (通常は匿名の内部クラス) は、コールバック関数オブジェクトそのものです。 Java で関数オブジェクト (クロージャーとも呼ばれます) を渡したい場合は、これを行う必要があります。

いいねを押す +0
黄舟

ずっと前、私が Java を学んでいたとき、私もクラスメートにこの質問をしました。あなたが採用した人は、これが本質的にはメソッド呼び出しであることをすでに明確にしていました。
実際、授業を注意深く聞いて、授業後に先生が書いたコードを注意深く入力していれば、問題は理解できます。
確かなのは、私はいつも問題を先送りして理解するのが好きだということです。後で出すことはできません。
1 日あたり 700 行以上の、より多くのコードを記述することをお勧めします。
入力するコードがないと思いますか?他の人が考え出した質問をするときは、コードを 3 回入力する必要があります。コードを入力しない場合は、意味のある小さなプログラムをいくつか入力してください。
コーディングにこだわるということは、最初から強くあり続けることを意味します。

いいねを押す +0
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート