最近也開始慢慢的學(xué)習(xí)些Kotlin的知識,畢竟人家Google認(rèn)了親兒子,我們做小弟的沒有理由忽略這一事實,所以決定開始慢慢探索Kotlin中未知的世界。
就拿最近一直在研究的CommonSelector的例子,來說說個人對Kotlin知識點的理解。
構(gòu)造一個CommonSelector類
var popupWindow: PopupWindow? = null
var popupWindowView: View? = null
var listview: ListView? = null
var linearlayout: LinearLayout? = null
var params: LinearLayout.LayoutParams? = null
var paramstv: LinearLayout.LayoutParams? = null
var textv: TextView? = null
/**
* CommonSelector簡單的選擇器
* @param activity 當(dāng)前界面activity
* @param v popwindow顯示位置的參照物
* @param list popwindow上顯示的數(shù)據(jù)
* @param callback 回調(diào)接聽,將選擇的數(shù)據(jù)穿出進行相應(yīng)操作
*/
class CommonSelector(activity: Activity, val v: View, val list: ArrayList<String>, val callback: OnSelectClickListener) {
init{
//to do something
}
}
因為kotlin中的類定義同時也是構(gòu)造函數(shù),這個時候是不能進行操作的,所以kotlin增加了一個新的關(guān)鍵字init用來處理類的初始化問題,init模塊中的內(nèi)容可以直接使用構(gòu)造函數(shù)的參數(shù)。
代碼構(gòu)建一個View
然后我們進行to do something,思路如下:
1、先構(gòu)建一個顯示的View,后面為了放入PopWindow。
2、構(gòu)建一個PopWindow,進行PopWindow的一些設(shè)置。
3、對PopWindow上的控件進行監(jiān)聽,并進行一些操作。
4、對PopWindow進行顯示,并控制在父控件的相對位置
init {
/**顯示的布局**/
//設(shè)置LinearLayout布局
linearlayout = LinearLayout(activity)
params = LinearLayout.LayoutParams(matchParent, matchParent)
params!!.margin = 30
params!!.gravity = Gravity.BOTTOM
linearlayout!!.layoutParams = params
linearlayout!!.orientation = LinearLayout.VERTICAL
// var draw: Drawable = ColorDrawable()
// draw.alpha = 0
// linearlayout!!.backgroundDrawable = draw
// linearlayout!!.padding = 30
// linearlayout!!.background.alpha = 0
// linearlayout!!.setDrawingCacheBackgroundColor(Color.argb(0, 255, 255, 255))
linearlayout!!.backgroundColor = Color.argb(255, 0, 255, 0)
//設(shè)置listview布局
listview = ListView(activity)
listview!!.layoutParams = params
listview!!.setBackgroundColor(Color.RED)
//設(shè)置listview的divider的顏色及寬度
listview!!.divider = ColorDrawable(Color.BLACK)
listview!!.dividerHeight = 1
//將listview添加入Linearlayout
linearlayout!!.addView(listview)
//設(shè)置取消按鈕
paramstv = LinearLayout.LayoutParams(matchParent, 150)
paramstv!!.bottomMargin = 30
paramstv!!.leftMargin = 30
paramstv!!.rightMargin = 30
textv = TextView(activity)
textv!!.text = "取消"
textv!!.gravity = Gravity.CENTER
textv!!.layoutParams = paramstv
textv!!.textSize = 18f
textv!!.textColor = Color.BLUE
textv!!.typeface = DEFAULT_BOLD
textv!!.setBackgroundColor(Color.RED)
//將取消按鈕添加入Linearlayout
linearlayout!!.addView(textv)
initPop()
}
我花了大片代碼去構(gòu)建一個View,其實很簡單,如下圖所示:

【~啪~啪~啪,敲黑板】這里還遺留了一個問題,在
linearlayout!!.backgroundColor = Color.argb(255, 0, 255, 0)這里設(shè)置linearlayout的背景,始終無法設(shè)置成透明的樣式,請教哪位大神能否幫助解決下,感謝感謝??。Color.argb(0, 0, 255, 0)這樣設(shè)置也只能將背景設(shè)置成白色,就是如圖綠色部分,百思不得騎姐啊,架~架~
代碼構(gòu)建一個popupWindow
private fun initPop() {
popupWindowView = (linearlayout as View?)!!
val dw: ColorDrawable = ColorDrawable(Color.WHITE)
popupWindow = PopupWindow(popupWindowView, matchParent, wrapContent, true)
popupWindow!!.setBackgroundDrawable(dw)
//點擊popipview之外監(jiān)聽事件
//popupWindow!!.setOnDismissListener { }
initEvent()
}
言簡意賅,每句代碼的意思,就像人如其名一樣,假如有不懂,可以留言,一起交流交流。
設(shè)置Listview和texttv的監(jiān)聽事件
private fun initEvent() {
var adapterr = TodoAdapter(list)
listview!!.adapter = adapterr
listview!!.onItemClick { adapterView, view, i, l ->
popupWindow!!.dismiss()
callback.onCommonItemSelect(i)
}
//取消按鈕監(jiān)聽事件
textv!!.onClick { popupWindow!!.dismiss() }
}
這段代碼中間有一個Lamda表達式,其中adapterView ``view ``l是指三個參數(shù),即listview的ItemClick的單機事件,每當(dāng)單擊Item,即popupWindow執(zhí)行消失動作,并且,將需要傳遞數(shù)據(jù)出去接口處。
【啪啪啪,敲黑板】這里有個TodoAdapter設(shè)配置,我下面詳細說下。這個也是Kotlin中,亮點之處。(純個人見解)
寫一個popupWindow顯示的方法
fun showPop(): Unit {
if (popupWindow!!.isShowing) {
return
}
if (list.size > 7) {
popupWindow!!.height = 700
}
popupWindow!!.showAtLocation(v, Gravity.BOTTOM, 0, 0)
}
這里我為什么要單獨寫一個方法進行popupWindow的顯示,因為,在我們顯示popupWindow的時候,將設(shè)置它的高度,進行一些設(shè)置,顧這樣設(shè)計比較合理,至于popupWindow顯示位置,有很多中方法,比如“showAtLocation``showAsDropDown”,這個顯示位置,我后面單獨書寫一篇文章來述說。
單獨寫TodoAdapter適配器的類
class TodoAdapter(val list: ArrayList<String>) : BaseAdapter() {
override fun getView(i: Int, v: View?, parent: ViewGroup?): View {
return with(parent!!.context) {
var taskNum: Int = i + 1
//Layout for a list view item
linearLayout {
textView {
gravity = Gravity.CENTER
text = list[i]
textSize = 16f
textColor = Color.BLUE
padding = dip(5)
}.lparams(matchParent, wrapContent)
}
}
}
override fun getItem(position: Int): Any {
return list[position]
}
override fun getItemId(p0: Int): Long {
return 0L
}
override fun getCount(): Int {
return list.size
}
}
很奇怪,對吧,我連xml文件居然都沒有使用到,就可以完成一個適配器的書寫,更奇怪的是,我這個CommonSelector連一個xml文件都沒有使用到。最重要的部分就是如何返回一個View,如下
return with(parent!!.context) {
var taskNum: Int = i + 1
//Layout for a list view item
linearLayout {
textView {
gravity = Gravity.CENTER
text = list[i]
textSize = 16f
textColor = Color.BLUE
padding = dip(5)
}.lparams(matchParent, wrapContent)
}
}
這里使用了一個Context的擴展方法linearLayout進行了View的實現(xiàn)。詳細的可以進入源代碼進行查看。里面的一些細節(jié)參數(shù)設(shè)置,也就順理成章了。假如這里有不懂的,可以留言一起交流交流。
整個
CommonSelector寫下來,其實其中還是有坑的存在的,就像我的Popwindow的布局為什么不能像適配器里面的布局一樣的寫,那是因為Context的擴展方法里面已經(jīng)addview添加進去了一個view,在構(gòu)建Popwindow的時候,再第二次加入View的時候,就會報錯了。
不過整個類里面還遺留了一個問題,就是背景設(shè)置成透明的樣式,始終無法實現(xiàn),是否有興趣的朋友一起交流下,看看如何實現(xiàn),這樣就完美了。
【啪啪啪~敲黑板】「我怎么發(fā)現(xiàn)我一直在敲黑板,哈哈」
整個類沒有用到xml文檔,固然需配置一個compile 'org.jetbrains.anko:anko-sdk15:0.9.1'的庫
不過沒有xml文檔,也是純?yōu)榱司毩?xí)語法。
針對
android中xml文件能不能干掉這一問題。
anko的布局是一個比較有爭議的東西,它雖然號稱有性能優(yōu)勢,但我測試過沒有很明顯;另外,類型安全的優(yōu)勢其實在有kotlin-android-extensions之后也不明顯了。
但問題在于,它不能實時preview(必須編譯),而且用起來也不是很簡單,對于初學(xué)者其實不是很友好。
所以,官方也是說我們只是提供了一種布局的途徑,并不是說要干掉 xml。
第一次寫
簡書,還請各位輕拍,純屬鞏固知識,交流為目的。
一個簡單的功能,給我寫的這么復(fù)雜,我也是醉了,哈哈~
結(jié)尾添加一個 我們應(yīng)該如何使用它呢?
直接上代碼, 如下
testtv.onClick {
commonSelector = CommonSelector(this,
testtv,
list,
object : CommonSelector.OnSelectClickListener {
override fun onCommonItemSelect(postions: Int) {
toast(list[postions])
}
})
commonSelector!!.showPop()
}