2017-05-22 31 views
1

我在Android項目中實現了SpinnerAdapter。所以我必須重寫getView(i: Int, convertView: View, parent: ViewGroup)方法。因此convertView在這裏是爲了重用現有視圖並減少內存使用和GC發生。所以,如果它是null我必須創建視圖和使用已經創建否則。如何使Kotlin中的方法參數變爲可變?

所以其實我不得不寫這樣的事情(由谷歌正式recomended):

if (view == null) { 
    view = View.inflate(context, R.layout.item_spinner, parent) 
    view.tag(Holder(view)) 
} else { 
    (view.tag as Holder).title.text = getItem(i) 
} 

但科特林不允許寫PARAM。 我在互聯網上發現的是一個官方blog post,說這是不可能的,因爲它是自2013年2月以來。

所以我想知道是否有任何解決方法?

+3

使用一個獨立的變量。沒有必要爲參數分配一個值。 – Henry

+0

比'convertView' PARAM永遠是空,因此每一次新的視圖將被創建。它使意見回收機制完全無用 –

+2

@ oleg.semen沒有,如果從'getView'方法'View'稍後將用作'convertView'返回非空'View' - 使用一個單獨的變量作爲亨利說 – pskink

回答

3

有兩個問題在這裏。

首先,您錯誤地認爲在Java中修改view會執行任何超出當前函數範圍的內容。它不是。您將該參數設置爲新值不會影響本地功能範圍以外的任何內容。

View getView(int i, View view, ViewGroup parent) { 
    // modify view here does nothing to the original caller reference to view 
    // but returning a view does do something 
} 

接着,在科特林所有參數都final(JVM改性劑,也一樣final改性劑中的Java)。這段代碼的科特林if報表版本將是:

fun getView(i: Int, view: View?, parent: ViewGroup): View { 
    return if (view == null) { 
     val tempView = View.inflate(context, R.layout.item_spinner, parent) 
     tempView.tag(Holder(tempView)) 
     tempView 
    } else { 
     (view.tag as Holder).title.text = getItem(i) 
     view 
    } 
} 

或避免新的局部變量:

fun getView(i: Int, view: View?, parent: ViewGroup): View { 
    return if (view == null) { 
     View.inflate(context, R.layout.item_spinner, parent).apply { 
      tag(Holder(this)) // this is now the new view 
     } 
    } else { 
     view.apply { (tag as Holder).title.text = getItem(i) } 
    } 
} 

fun getView(i: Int, view: View?, parent: ViewGroup): View { 
    if (view == null) { 
     val tempView = View.inflate(context, R.layout.item_spinner, parent) 
     tempView.tag(Holder(tempView)) 
     return tempView 
    } 

    (view.tag as Holder).title.text = getItem(i) 
    return view 
} 

或使用?.?:空運營商合併apply()

fun getView(i: Int, view: View?, parent: ViewGroup): View { 
    return view?.apply { 
       (tag as Holder).title.text = getItem(i) 
      } ?: View.inflate(context, R.layout.item_spinner, parent).apply { 
        tag(Holder(this)) 
       } 
} 

還有另外10種變化,但您可以嘗試看看您喜歡什麼。

它被認爲不是一個好的做法(但允許)通過使用相同的名稱來映射變量,這就是爲什麼它是一個編譯器警告。以及爲什麼你看到上面的變量名稱從view更改爲tempView

0

正式來說,你不能重寫一個方法參數。你可以做的最好的是「影」參數變量。

所以,你可以做到這一點類似於(不知道爲什麼你會想,雖然影子,但你可以)

getView(i: Int, view: View?, parent: ViewGroup) { 
    val view = view ?: View.inflate(context, R.layout.item_spinner, parent) 
         .apply { tag(Holder(view)) } 
    (view.tag as Holder).title.text = getItem(i) 
} 
0

有一個骯髒但實用的方法。

fun a(b: Int) { 
    var b = b 
    b++ // this compiles 
} 
相關問題