Android开发,addlistener和setlistener的区别

来源:互联网 发布:2017苹果春季发布会mac 编辑:程序博客网 时间:2024/06/16 01:25

做Android开发稍微久一点的都知道,android之前的监听器基本都是setlistener,比如setOnClickListener,setTextChangeListener。

但是后来,android中很多的setlistener都被废弃了,用addlistener来替代,比如上面的setTextChangeListener。

本文主要就是用于探讨setlistener和addlistener的区别。

我们就以setOnClickListener和addTextChangedListener举例

1、查看源码

/**     * Register a callback to be invoked when this view is clicked. If this view is not     * clickable, it becomes clickable.     *     * @param l The callback that will run     *     * @see #setClickable(boolean)     */    public void setOnClickListener(@Nullable OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        getListenerInfo().mOnClickListener = l;    }
/**     * Adds a TextWatcher to the list of those whose methods are called     * whenever this TextView's text changes.     * <p>     * In 1.0, the {@link TextWatcher#afterTextChanged} method was erroneously     * not called after {@link #setText} calls.  Now, doing {@link #setText}     * if there are any text changed listeners forces the buffer type to     * Editable if it would not otherwise be and does call this method.     */    public void addTextChangedListener(TextWatcher watcher) {        if (mListeners == null) {            mListeners = new ArrayList<TextWatcher>();        }        mListeners.add(watcher);    }
可以看到,setListener直接是给View中的一个listener赋了值。
而addListener是将该listener添加到了一个arraylsit集合里面。
从这里我们可以猜测,setListener只能设置一个,addListenr可以设置多个。
下面我们来看看具体。

2、测试setListener

我在xml中设置了一个按钮

<Button        android:id="@+id/btn_test_setListener"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_margin="50dp"        android:text="set测试"/>
代码中:

class ListenerTestActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_listener_test)        btn_test_setListener.setOnClickListener {            Log.e("set1", "1-listener is clicked")        }        btn_test_setListener.setOnClickListener {            Log.e("set2", "2-listener is clicked")        }    }}
恩, 测试demo我使用的语言是kotlin,这里大家应该看得懂,也不复杂,也不影响结果,就不再写一个java版本了。
可以看到,我连续设置了两个点击事件给按钮。

11-08 11:10:56.508 16788-16788/com.stanny.xbtest E/set2: 2-listener is clicked11-08 11:10:57.475 16788-16788/com.stanny.xbtest E/set2: 2-listener is clicked11-08 11:10:57.866 16788-16788/com.stanny.xbtest E/set2: 2-listener is clicked
可以看到,只有第二个点击事件被调用了,而第一个完全被覆盖了。


3、测试addListener

et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    Log.e("add1", "1-listener is changed")                }            }        })        et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    Log.e("add2", "2-listener is changed")                }            }        })
这里我给我的输入框添加了两个监听,都是在判断输入文字长度为2时,打印一段log

11-08 11:14:49.050 21397-21397/com.stanny.xbtest E/add1: 1-listener is changed11-08 11:14:49.050 21397-21397/com.stanny.xbtest E/add2: 2-listener is changed

可以看到,两个监听,都被打印了。


4、进一步测试addListener

et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    finish()//修改位置                }            }        })        et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                   Log.e("add2", "2-listener is changed")                }            }        })
我们第一个监听直接finish掉当前activity,那么第二个还会执行么
11-08 11:30:48.601 6465-6636/com.stanny.xbtest E/add2: 2-listener is changed
可以看到,即使activity已经被finish掉了,第二个监听仍然会执行

那么,你可能会说了,因为这两个是同时发生的,所以才会出现仍然会执行。好,我们继续


5、再进一步测试

et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    finish()                }            }        })        et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    var timer = Timer()//修改位置                    timer.schedule(object : TimerTask() {                        override fun run() {                            Log.e("add2", "2-listener is changed")                        }                    }, 1000)                }            }        })

我们给第二个监听的打印,一个等待时间,而这时候,该activity已经被finish了

11-08 11:36:02.633 11617-11855/com.stanny.xbtest E/add2: 2-listener is changed

也是会执行的,我们的手机上,明明此时activity已经返回了上一级,但是log仍然打印出来了。

那还有没有什么问题?

有的,因为我们现在只是简单的打印了文字,和当前的activity的数据或者控件都没有联系,所以,会不会是这个原因呢?


6、最后一步测试

et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    finish()                }            }        })        et_test_addListener.addTextChangedListener(object : TextWatcher {            override fun afterTextChanged(p0: Editable?) {            }            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {            }            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {                if (et_test_addListener.text.length == 2) {                    var timer = Timer()                    timer.schedule(object : TimerTask() {                        override fun run() {                            Log.e("add2", "2-listener is changed")                            btn_test_setListener.setText("123")//修改位置                        }                    }, 1000)                }            }        })
可以看到,我在第二个延时操作的时候,不仅仅打印了log,还给一个按钮设置了文字。

之前我们怀疑因为没涉及到控件,所以不会报错,这次,我们测试在activity被finish掉之后,对控件进行操作。

因为已经finish了,我们也看不到按钮是否改变了文字,但是,我可以确定,没有产生崩溃,没有报错信息。


那么,我们想知道,这个activity真的已经被finish掉了么?还是说,要等到添加的监听都实现完了才会被finish。

这个问题,等有时间,我再来研究。


阅读全文
0 0
原创粉丝点击