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

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

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

membalas semua(5)
迷茫

Ini pada asasnya ialah panggilan kaedah. Katakan kita mempunyai dua kelas A dan B, dan kita menjangkakan untuk memanggil kaedah B pada masa tertentu dalam A. Kita boleh membiarkan A menyimpan rujukan kepada B dan membuat panggilan kaedah pada masa yang sesuai:

class B {
    void doSomething() {}
}

class A {
    private B b;
    
    public void setB(B b) {
        // 保持一个B的引用
        this.b = b;
    }
    
    public void testMethod() {
        // ...
        // 在A的某个时刻调用B的某个方法
        b.doSomething();
        // ...
    }
}

Kod di atas dilaksanakan pada masa tertentu dalam A (apabila sesuatu berlaku), kami memberitahu B untuk melakukan sesuatu Ini ialah mod mendengar yang mudah. Anda lihat, di sini bukanlah B memantau tindakan A sepanjang masa, tetapi A secara aktif mencetuskan kaedah B pada masa tertentu.

Di sini, gantikan B dengan Pendengar dan ia menjadi pendengar biasa.

Jadi kita boleh menulis subkelas B dan melaksanakan pendengar tersuai:

class SubB extends B {
    @override
    void doSomething() {}
}

void main() {
    A a = new A();
    // 给A设置我们自定义的监听器
    a.setB(new SubB());
    a.testMethod();
}

Dari segi corak reka bentuk, terdapat pendekatan yang disyorkan yang dipanggil "gunakan lebih banyak kombinasi dan kurang warisan", yang bermaksud anda harus menggunakan lebih banyak antara muka dan kurang warisan Mari tukar B di atas kepada antara muka:

interface B {
    void doSomething();
}

Kemudian gantikan pelaksanaan yang diwarisi sebelum ini dengan pelaksanaan antara muka:

class SubB implements B {
    void doSomething() {}
}
void main() {
    A a = new A();
    // 给A设置我们自定义的监听器
    a.setB(new SubB());
    a.testMethod();
}

Seperti yang anda boleh lihat, penggunaannya betul-betul sama seperti sebelum ini.

Ganti antara muka B dengan antara muka OnClickListener Adakah ia akan menjadi lebih jelas? Ini dipanggil 观察者模式 dalam corak reka bentuk.

Syorkan buku: "Corak Reka Bentuk Kepala Pertama", dua bab pertama memperkenalkan 策略模式 dan 观察者模式, iaitu apa yang saya nyatakan di atas.

迷茫

Tidak memahami pendengar secara literal Ia tidak memeriksa secara aktif sama ada masa berlaku, jadi tiada perkara seperti setiap saat.
Bagi kami, Pendengar dalam Android sebenarnya hanyalah Panggilan Balik, kaedah panggil balik. Ia adalah kaedah yang dipanggil oleh pemula peristiwa atau pengendali dalaman apabila peristiwa berlaku.
Kelas Pendengar yang ditulis oleh saya sendiri bukanlah untuk dapat mendengar peristiwa kerana ia mewarisi daripada si fulan, tetapi untuk mencari jalan untuk memberitahu pemula atau pengendali dalaman peristiwa bahawa apabila sesuatu peristiwa berlaku, kaedah yang ditentukan dalam Listener ini perlu dipanggil Ini juga Ini adalah proses setListener yang biasa dilakukan.

Logik ini telah disimpulkan dengan jelas dalam kod yang anda berikan.

大家讲道理

Ini adalah corak reka bentuk, hanya dipanggil pendengar Ia tidak dicetuskan secara aktif, tetapi pasif. Setelah anda memahami corak ini, anda boleh menulis sendiri. Inilah yang biasa kami panggil panggilan balik.

阿神

Java's Listener ialah antara muka yang menentukan fungsi panggil balik. Kelas pelaksanaan Listener (biasanya kelas dalaman tanpa nama) ialah objek fungsi panggil balik itu sendiri. Jika anda ingin lulus objek fungsi (juga dipanggil penutupan) dalam Java, anda perlu melakukan ini.

黄舟

Suatu masa dahulu, semasa saya belajar Java, saya juga bertanya kepada rakan sekelas saya soalan ini Orang yang anda angkat telah menjelaskan dengan jelas bahawa ini pada asasnya adalah panggilan kaedah.
Sebenarnya, selagi anda mendengar dengan teliti di dalam kelas dan dengan teliti menaip kod yang ditulis oleh guru selepas kelas, anda akan memahami masalahnya
Apa yang pasti saya sentiasa suka menangguhkan masalah dan memikirkannya keluar kemudian, ini tidak mungkin.
Adalah disyorkan untuk menulis lebih banyak kod, tidak kurang daripada 700 baris setiap hari.
Adakah anda rasa tiada kod untuk ditaip? Apabila bertanya soalan yang telah diketahui oleh orang lain, anda mesti menaip kod tiga kali Jika anda tidak menaip kod, taip beberapa program kecil yang bermakna.
Berpegang kepada pengekodan bermakna kekal kuat dari awal.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan