重构我们的代码

现在是时候使用Kotlin Android Extensions来修改我们的代码了。修改相当简单。

我们从MainActivity开始。我们当前只是使用了forecastList的RecyclerView。但是我们可以简化一点代码。首先,为activity_mainXML增加手工import:

  1. import kotlinx.android.synthetic.activity_main.*

之前说过,我们使用id来访问views。所以我要修改RecyclerView的id,不使用下划线,让它更加适合Kotlin变量的名字。XML最后如下:

  1. <FrameLayout
  2. xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent">
  5. <android.support.v7.widget.RecyclerView
  6. android:id="@+id/forecastList"
  7. android:layout_width="match_parent"
  8. android:layout_height="match_parent"/>
  9. </FrameLayout>

然后现在,我们可以不需要find这一行了:

  1. override fun onCreate(savedInstanceState: Bundle?) {
  2. super.onCreate(savedInstanceState)
  3. setContentView(R.layout.activity_main)
  4. forecastList.layoutManager = LinearLayoutManager(this)
  5. ...
  6. }

这已经是最小的简化了,因为这个布局非常简单。但是ForecastListAdapter也可以从这个插件中受益。这里你可以使用一个装置来绑定这些属性到view中,它可以帮助我们移除所有ViewHolderfind代码。

首先,为item_forecast增加手工导入:

  1. import kotlinx.android.synthetic.item_forecast.view.*

然后现在我们可以在ViewHolder中使用包含在itemView中的属性。实际上你可以在任何view中使用这些属性,但是很显然如果view不包含要获取的子view就会奔溃。

现在我们可以直接访问view的属性了:

  1. class ViewHolder(view: View, val itemClick: (Forecast) -> Unit) :
  2. RecyclerView.ViewHolder(view) {
  3. fun bindForecast(forecast: Forecast) {
  4. with(forecast){
  5. Picasso.with(itemView.ctx).load(iconUrl).into(itemView.icon)
  6. itemView.date.text = date
  7. itemView.description.text = description
  8. itemView.maxTemperature.text = "${high.toString()}￿￿"
  9. itemView.minTemperature.text = "${low.toString()}￿￿"
  10. itemView.onClick { itemClick(forecast) }
  11. }
  12. }
  13. }

Kotlin Android Extensions插件帮助我们减少了很多模版代码,并且简化了我们访问view的方式。从库中检出最新的代码吧。