概述
擴充套件函式:指在一個類上增加一種新的行為,甚至我們沒有這個類程式碼的訪問許可權。類似Java中很多帶有static方法的工具類。
優勢:不需要在呼叫方法的時候把整個物件當作引數傳入。而是像是屬於擴充套件類的一樣,可以使用this關鍵字和呼叫所有public方法。
應用場景
參考anko-common 依賴包中ContextUtils、Dialogs
等檔案的寫法
// 屬性擴充套件
// 注意:anko-common包中沒有擴充套件V4包中的Fragment,需要自己擴充套件,否則無法獲取到ctx屬性
val Fragment.ctx: Context
get() = activity
// 屬性擴充套件
val Context.ctx: Context
get() = this
// 函式擴充套件
inline fun <reified T : View> Activity.find(id: Int): T = findViewById(id) as T
inline fun <reified T : View> Fragment.find(id: Int): T = view?.findViewById(id) as T
// 函式擴充套件
fun Context.toast(textResource: Int) = Toast.makeText(this, textResource, Toast.LENGTH_SHORT).show()
fun Context.toast(text: CharSequence) = Toast.makeText(this, text, Toast.LENGTH_SHORT).show()
inline fun AnkoContext<*>.longToast(textResource: Int) = ctx.longToast(textResource)
// ...略...
複製程式碼
1. 屬性的擴充套件
val Fragment.ctx: Context
get() = activity
public var TextView.text: CharSequence
get() = getText()
set(v) = setText(v)
複製程式碼
2. 函式的擴充套件
fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, message, duration).show()
}
複製程式碼
應用
擴充套件EditText的TextWatcher監聽
fun EditText.beforeTextChanged(action: (s: CharSequence?, start: Int, count: Int, after: Int)->Unit) = textWatch(before = action)
fun EditText.onTextChanged(action: (s: CharSequence?, start: Int, count: Int, after: Int)->Unit) = textWatch(change = action)
fun EditText.afterTextChanged(action: (s: Editable?)->Unit) = textWatch(after = action)
fun EditText.textWatch(
before: ((s: CharSequence?, start: Int, count: Int, after: Int)->Unit)? = null,
change: ((s: CharSequence?, start: Int, before: Int, count: Int)->Unit)? = null,
after: ((s: Editable?) -> Unit)? = null
) : EditText {
return apply { // 這裡返回EditText
val listener = object : TextWatcher{
override fun afterTextChanged(s: Editable?) {
after?.invoke(s)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
before?.invoke(s, start, count, after)
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
change?.invoke(s, start, before, count)
}
}
addTextChangedListener(listener)
}
}
複製程式碼
使用:
class JokeListFragment : Fragment() {
override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
val view = inflater?.inflate(R.layout.joke_fragment_joke_list, null)
return view
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// 實現鏈式呼叫
editText.beforeTextChanged {
s, start, count, after -> Log.d("Joke", "before =$s")
}.onTextChanged {
s, start, count, after -> Log.d("Joke", "change =$s")
}.afterTextChanged {
s ->
Log.d("Joke", "after =${s.toString()}")
toast(s.toString())
}
}
}
複製程式碼