Kotlin之"零"xml文件的Common

作者: STTXGR | 来源:发表于2017-10-18 20:22 被阅读51次

    最近也开始慢慢的学习些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,其实很简单,如下图所示:

    WechatIMG140.jpeg

    【~啪~啪~啪,敲黑板】这里还遗留了一个问题,在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()
        }
    

    言简意赅,每句代码的意思,就像人如其名一样,假如有不懂,可以留言,一起交流交流。

    设置Listviewtexttv的监听事件

        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文档,也是纯为了练习语法。

    针对androidxml文件能不能干掉这一问题。
    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()
            }
    

    相关文章

      网友评论

      本文标题:Kotlin之"零"xml文件的Common

      本文链接:https://www.haomeiwen.com/subject/fpesuxtx.html