使用拓展方法+內(nèi)聯(lián)函數(shù)前
viewPager.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
}
override fun onPageSelected(position: Int) {
val radioButton = rg_tabs.getChildAt(position) as RadioButton
radioButton.isChecked = true
}
override fun onPageScrollStateChanged(state: Int) {
}
})
使用拓展方法+內(nèi)聯(lián)函數(shù)后
viewPager.addListener {
val radioButton = rg_tabs.getChildAt(it) as RadioButton
radioButton.isChecked = true
}
實現(xiàn)原理
看上面的簡化寫法耕捞,你一定會有兩個疑問:
- viewPager哪來的addListener方法
- 上面的代碼是怎么關(guān)聯(lián)到onPageSelected方法的
第一個問題很簡單负溪,拓展函數(shù)就可以了逃沿,我們定義了一個如下的拓展函數(shù)
inline fun ViewPager.addListener(
crossinline onScrollStateChanged: (state: Int) -> Unit = {},
crossinline onScrolled: (position: Int, positionOffset: Float, positionOffsetPixels: Int) -> Unit = { position, positionOffset, positionOffsetPixels -> },
crossinline onSelected: (position: Int) -> Unit = {}
) {
val listener = object : ViewPager.OnPageChangeListener {
override fun onPageScrollStateChanged(state: Int) {
onScrollStateChanged(state)
}
override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {
onScrolled(position, positionOffset, positionOffsetPixels)
}
override fun onPageSelected(position: Int) {
onSelected(position)
}
}
addOnPageChangeListener(listener)
}
第二個問題婴渡,看上面的拓展函數(shù),我們就知道凯亮,其實在調(diào)用addListener時边臼,就是創(chuàng)建了一個ViewPager.OnPageChangeListener對象,然后添加到addOnPageChangeListener中假消,本質(zhì)上我們最原始的代碼沒有區(qū)別
按照上面的拓展方法柠并,其實我們應該這么寫:
viewPager.addListener (onSelected = { position->
val radioButton = rg_tabs.getChildAt(position) as RadioButton
radioButton.isChecked = true
})
但是,實際上富拗,上面的代碼可以有兩個簡化
- 如果方法的參數(shù)的最后一個是lambda表達式臼予,可以不寫表達式的參數(shù),將表達式的方法體放到外面去
viewPager.addListener { position->
val radioButton = rg_tabs.getChildAt(position) as RadioButton
radioButton.isChecked = true
}
- 如果lambda表達式的入?yún)⒅挥幸粋€啃沪,入?yún)⒖梢允÷哉呈埃胕t代替
vp.addListener {
val radioButton = rg_tabs.getChildAt(it) as RadioButton
radioButton.isChecked = true
}
好了,最終簡化版完成了创千,enjoy吧缰雇。
其實入偷,這個簡化技巧可以用到很多地方,比如網(wǎng)絡請求械哟,可以將什么網(wǎng)絡請求疏之、線程切換、序列化等等都放在拓展方法內(nèi)部暇咆,將成功的回調(diào)方法做成lambda表達式放在參數(shù)的最后一位锋爪,前面也可以加一個錯誤回調(diào)的lambda表達式參數(shù),但一般情況下可以省略糯崎,用默認實現(xiàn)就好几缭,這樣代碼就可以寫成
request.addListener {
handleResponse(it)
}