Kotlin之"零"xml文件的CommonSelector淺探

最近也開始慢慢的學(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,其實很簡單,如下圖所示:

WechatIMG140.jpeg

【~啪~啪~啪,敲黑板】這里還遺留了一個問題,在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è)置Listviewtexttv的監(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í)語法。

針對androidxml文件能不能干掉這一問題。
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()
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容