做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.     * 

* 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(); } mListeners.add(watcher); }

可以看到,setListener直接是给View中的一个listener赋了值。 而addListener是将该listener添加到了一个arraylsit集合里面。 从这里我们可以猜测,setListener只能设置一个,addListenr可以设置多个。 下面我们来看看具体。

2、测试setListener

我在xml中设置了一个按钮

代码中:

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。

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


更多相关文章

  1. Android(安卓)SeekBar
  2. android——Seneor(获得数据值流程以及同时监听多个sensor)
  3. Android(安卓)单元测试 及 覆盖率
  4. Android中使用Junit进行单元测试
  5. Android中的菜单-ContextMenu,PopupMenu
  6. android netd和kernel&frameworks的通信逻辑
  7. Android中Gallery和ImageSwitcher同步自动(滚动)播放图片库
  8. android AlertDialog对话框
  9. 关于如何高效率开发一个Android(安卓)App

随机推荐

  1. android工程字符串多语言翻译遗漏查找工
  2. Android之adt 23找不到NDK路径设置解决方
  3. android 的文本框输入类型
  4. android横竖屏切换后不重建不销毁Activit
  5. Android(安卓)RecyclerView
  6. Android(安卓)设置Activity样式 透明度
  7. Android非Kotlin支持项目添加Kotlin代码
  8. Android黄色警告汇总
  9. 关于android应用程序的入口
  10. android 中给图片加圆角效果