最近也開始慢慢的學習些Kotlin
的知識堡纬,畢竟人家Google認了親兒子须教,我們做小弟的沒有理由忽略這一事實墅诡,所以決定開始慢慢探索Kotlin
中未知的世界序臂。
就拿最近一直在研究的CommonSelector
的例子拂盯,來說說個人對Kotlin
知識點的理解。
構造一個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 當前界面activity
* @param v popwindow顯示位置的參照物
* @param list popwindow上顯示的數據
* @param callback 回調接聽卵惦,將選擇的數據穿出進行相應操作
*/
class CommonSelector(activity: Activity, val v: View, val list: ArrayList<String>, val callback: OnSelectClickListener) {
init{
//to do something
}
}
因為kotlin
中的類定義同時也是構造函數阻肿,這個時候是不能進行操作的,所以kotlin
增加了一個新的關鍵字init
用來處理類的初始化問題沮尿,init
模塊中的內容可以直接使用構造函數的參數丛塌。
代碼構建一個View
然后我們進行to do something,思路如下:
1畜疾、先構建一個顯示的View
赴邻,后面為了放入PopWindow
。
2啡捶、構建一個PopWindow
姥敛,進行PopWindow
的一些設置。
3瞎暑、對PopWindow
上的控件進行監(jiān)聽彤敛,并進行一些操作。
4了赌、對PopWindow
進行顯示墨榄,并控制在父控件的相對位置
init {
/**顯示的布局**/
//設置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)
//設置listview布局
listview = ListView(activity)
listview!!.layoutParams = params
listview!!.setBackgroundColor(Color.RED)
//設置listview的divider的顏色及寬度
listview!!.divider = ColorDrawable(Color.BLACK)
listview!!.dividerHeight = 1
//將listview添加入Linearlayout
linearlayout!!.addView(listview)
//設置取消按鈕
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()
}
我花了大片代碼去構建一個View
,其實很簡單,如下圖所示:
【~啪~啪~啪勿她,敲黑板】這里還遺留了一個問題袄秩,在
linearlayout!!.backgroundColor = Color.argb(255, 0, 255, 0)
這里設置linearlayout
的背景,始終無法設置成透明的樣式嫂拴,請教哪位大神能否幫助解決下,感謝感謝??贮喧。Color.argb(0, 0, 255, 0)
這樣設置也只能將背景設置成白色筒狠,就是如圖綠色
部分,百思不得騎姐啊,架~架~
代碼構建一個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()
}
言簡意賅箱沦,每句代碼的意思辩恼,就像人如其名一樣,假如有不懂谓形,可以留言灶伊,一起交流交流。
設置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
是指三個參數聘萨,即listview
的ItemClick的單機事件,每當單擊Item
,即popupWindow
執(zhí)行消失動作童太,并且米辐,將需要傳遞數據出去接口處胸完。
【啪啪啪,敲黑板】這里有個TodoAdapter
設配置翘贮,我下面詳細說下赊窥。這個也是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
的時候芍耘,將設置它的高度址遇,進行一些設置,顧這樣設計比較合理齿穗,至于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é)參數設置蛆封,也就順理成章了。假如這里有不懂的勾栗,可以留言一起交流交流惨篱。
整個
CommonSelector
寫下來,其實其中還是有坑的存在的围俘,就像我的Popwindow
的布局為什么不能像適配器里面的布局一樣的寫砸讳,那是因為Context
的擴展方法里面已經addview
添加進去了一個view,在構建Popwindow
的時候界牡,再第二次加入View
的時候簿寂,就會報錯了。
不過整個類里面還遺留了一個問題宿亡,就是背景設置成透明的樣式常遂,始終無法實現(xiàn),是否有興趣的朋友一起交流下挽荠,看看如何實現(xiàn)烈钞,這樣就完美了泊碑。
【啪啪啪~敲黑板】「我怎么發(fā)現(xiàn)我一直在敲黑板,哈哈」
整個類沒有用到xml
文檔毯欣,固然需配置一個compile 'org.jetbrains.anko:anko-sdk15:0.9.1'
的庫
不過沒有xml
文檔馒过,也是純?yōu)榱司毩曊Z法。
針對
android
中xml
文件能不能干掉這一問題酗钞。
anko
的布局是一個比較有爭議的東西腹忽,它雖然號稱有性能優(yōu)勢,但我測試過沒有很明顯砚作;另外窘奏,類型安全的優(yōu)勢其實在有kotlin-android-extensions
之后也不明顯了。
但問題在于葫录,它不能實時preview(必須編譯)着裹,而且用起來也不是很簡單,對于初學者其實不是很友好米同。
所以骇扇,官方也是說我們只是提供了一種布局的途徑,并不是說要干掉 xml面粮。
第一次寫
簡書
少孝,還請各位輕拍,純屬鞏固知識熬苍,交流為目的稍走。
一個簡單的功能,給我寫的這么復雜柴底,我也是醉了婿脸,哈哈~
結尾添加一個 我們應該如何使用它呢?
直接上代碼, 如下
testtv.onClick {
commonSelector = CommonSelector(this,
testtv,
list,
object : CommonSelector.OnSelectClickListener {
override fun onCommonItemSelect(postions: Int) {
toast(list[postions])
}
})
commonSelector!!.showPop()
}