1. 程式人生 > >讓你的程式碼減少三倍!使用kotlin開發Android(五) 監聽器

讓你的程式碼減少三倍!使用kotlin開發Android(五) 監聽器

在前面的部落格中,有一個栗子,是點選按鈕轉跳的監聽器。

 button.setOnClickListener {
      val user = User("name")
      user.id = "100"
      SecondActivity.startActivity(this,user)
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

可以看到,不用再new一個OnClickListener了。實際上這種寫法是lambda的一種簡略模式,通常情況下匿名內部類可以以如下表現形式展示:

button.setOnClickListener {
      view-> toast(view.id
.toString()) }
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

簡單來說就是->左邊為引數,右面為結果。其過程相當於


button.setOnClickListener(new OnClickListener(){
    @Override
    public void onClick(View view){
        toast(view.id.toString())   
    }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

從以上栗子可以看出,lambda可以極大簡化我們的程式碼。當左面引數沒有使用到的時候,可以省略掉整個左半部分”view->”,就如同第一個程式碼片一樣。

給RecyclerView加監聽

在MainActivity裡新增一個RecyclerView。並且新建一個介面卡起名MainAdapter


import kotlinx.android.synthetic.main.item_main.view.*
classMainAdapter: RecyclerView.Adapter<MainAdapter.ViewHolder>() {
  override fun onBindViewHolder(holder: ViewHolder?, position: Int) {

  //改變作用域,with{}都是屬於itemView
    with(holder
?.itemView!!)
{ tv_content.text = "第 $position 條資料" } } override fun getItemCount(): Int { return 5 } override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): ViewHolder { return ViewHolder(View.inflate(parent?.context, R.layout.item_main,null)) } classViewHolder(itemView: View?) : RecyclerView.ViewHolder(itemView) { } }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

像往常一樣寫一個RecyclerView的佈局

注意這個介面卡裡使用的一些小技巧

1.with改變作用域,如果你有一大堆需要重複寫的字首,則可以使用with改變作用域。如:

mBinding?.tvName?.text = "張三"
mBinding?.tvContent?.text = "張三跟李四有py交易"
mBinding?.ivIcon.resouce = R.drawable.icon
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

可以改為

with(mBinding){
    tvName?.text = "張三"
    tvContent?.text = "張三跟李四有py交易"
    ivIcon.resouce = R.drawable.icon
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

2.在頭部匯入

import kotlinx.android.synthetic.main.item_main.view.*
  • 1
  • 1

這樣就可以免去萬惡的findviewbyid

3.View.infalte()代替LayoutInfalter.form().infalte()

這個沒啥好說的,省點程式碼而已~~

4.String模板輸出,類似於C語言的print

新增監聽器

大家都知道,有個簡便的方法就是直接給itemView添加個OnClickListener()~

所以在onBindViewHolder()開刀,注意寫法,這裡與Java有不同

classMainAdapter : RecyclerView.Adapter<MainAdapter.ViewHolder>() {
  var mListener: ((pos: Int) -> Unit)? = null

  fun setOnItemClickListener(listener: ((pos: Int) -> Unit)){
    mListener = listener
  }
  override fun onBindViewHolder(holder: ViewHolder?, position: Int) {
    with(holder?.itemView!!) {
      tv_content.text = "第 $position 條資料"
      setOnClickListener { mListener?.invoke(position) }
    }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

其中給了一個函式變數mListener, 他的輸入為int,返回值為Unit(kotlin的null,不過是個具體的物件)

var mListener: ((pos: Int) -> Unit)? = null
  • 1
  • 1

接下來給個set函式

fun setOnItemClickListener(listener: ((pos: Int) -> Unit)){
    mListener = listener
  }
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

這樣就完成了item監聽器的編寫,所以我們的Activity程式碼如下:

    val adapter = MainAdapter()
    recyclerView.adapter = adapter
    recyclerView.layoutManager = LinearLayoutManager(this)
    adapter.setOnItemClickListener { pos->toast("$pos") }
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

本文這就結束了(嫌文字太短?不要急啦,先去動手實踐下咯。。系列文章,既然挖了坑,就不會拖更的(吧..))

如果你是Android開發者,那麼你還可以來 wing的酒館:425983695來分享你的開發經驗哦