最近也开始慢慢的学习些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
上的控件进行监听,并进行一些操作。
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之外监听事件
//popupWindow!!.setOnDismissListener { }
initEvent()
}
言简意赅,每句代码的意思,就像人如其名一样,假如有不懂,可以留言,一起交流交流。
设置Listview
和texttv
的监听事件
private fun initEvent() {
var adapterr = TodoAdapter(list)
listview!!.adapter = adapterr
listview!!.onItemClick { adapterView, view, i, l ->
popupWindow!!.dismiss()
callback.onCommonItemSelect(i)
}
//取消按钮监听事件
textv!!.onClick { popupWindow!!.dismiss() }
}
这段代码中间有一个Lamda
表达式,其中adapterView ``view ``l
是指三个参数,即listview
的ItemClick的单机事件,每当单击Item
,即popupWindow
执行消失动作,并且,将需要传递数据出去接口处。
【啪啪啪,敲黑板】这里有个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
的实现。详细的可以进入源代码进行查看。里面的一些细节参数设置,也就顺理成章了。假如这里有不懂的,可以留言一起交流交流。
整个
CommonSelector
写下来,其实其中还是有坑的存在的,就像我的Popwindow
的布局为什么不能像适配器里面的布局一样的写,那是因为Context
的扩展方法里面已经addview
添加进去了一个view,在构建Popwindow
的时候,再第二次加入View
的时候,就会报错了。
不过整个类里面还遗留了一个问题,就是背景设置成透明的样式,始终无法实现,是否有兴趣的朋友一起交流下,看看如何实现,这样就完美了。
【啪啪啪~敲黑板】「我怎么发现我一直在敲黑板,哈哈」
整个类没有用到xml
文档,固然需配置一个compile 'org.jetbrains.anko:anko-sdk15:0.9.1'
的库
不过没有xml
文档,也是纯为了练习语法。
针对
android
中xml
文件能不能干掉这一问题。
anko
的布局是一个比较有争议的东西,它虽然号称有性能优势,但我测试过没有很明显;另外,类型安全的优势其实在有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()
}