2017-02-15 63 views
1

我有以下Kotlin/Anko/Android活动。是否有干净的DRY方式来从HTTP请求JSON更新多个textViews?

import android.os.Bundle 
import android.support.v7.app.AppCompatActivity 
import android.widget.TextView 
import com.fasterxml.jackson.module.kotlin.readValue 
import com.github.kittinunf.fuel.Fuel 
import eu.gwapi.laaketilaus.util.JSON 
import eu.gwapi.laaketilaus.util.Order 
import org.jetbrains.anko.find 
import org.jetbrains.anko.textView 
import org.jetbrains.anko.toast 
import org.jetbrains.anko.verticalLayout 

class OrderDetailsActivity : AppCompatActivity() { 

    override fun onCreate(savedInstanceState: Bundle?) { 
     super.onCreate(savedInstanceState) 
     val order_id: Long = intent.extras.getLong("order_id") 
     verticalLayout { 
      textView { 
       id = R.id.order_detail_customer 
      } 
      textView { 
       id = R.id.order_detail_address 
      } 
      textView { 
       id = R.id.order_detail_postal_code 
      } 
      textView { 
       id = R.id.order_detail_phone 
      } 
     } 
     getOrder(order_id) 
    } 

    fun getOrder(order_id: Long) { 
     Fuel.get("https://my.api.endpoint/" + order_id.toString()).responseString { request, response, result -> 
      val (json, err) = result 
      if (err != null) { 
       toast(err.toString()) 
      } else { 
       val order: Order = JSON.readValue(json!!) 
       find<TextView>(R.id.order_detail_customer).text = order.customer 
       find<TextView>(R.id.order_detail_address).text = order.address 
       find<TextView>(R.id.order_detail_postal_code).text = order.postal_code 
       find<TextView>(R.id.order_detail_phone).text = order.phone 
      } 
     } 
    } 
} 

对于像我这样顽固的pythonista,这似乎很静态和冗长的做法。

有没有更好的方法?

回答

1

由于只有TextView S和你只需要改变自己的文字,您可以简化代码通过以下方式:

  • 添加映射为Order性存储的ID:

    private val orderPropertyToTextViewId = mapOf(
         Order::customer to R.id.order_detail_customer, 
         Order::address to R.id.order_detail_address, 
         Order::postalCode to R.id.order_detail_postal_code, 
         Order::phone to R.id.order_detail_phone 
    ) 
    
  • 创建迭代地图上的观点:

    verticalLayout { 
        for ((property, textViewId) in orderPropertyToTextViewId) { 
         textView { id = textViewId } 
        } 
    } 
    
  • 更新文本迭代的地图上:

    for ((property, textViewId) in orderPropertyToTextViewId) { 
        findViewById<TextView>(textViewId).text = property.get(order) 
    } 
    

你可以更进一步,摆脱了ID和findViewById<TextView>(...)的,如果你存储TextView s数textView { ... }调用,而不是在标识返回地图,但这需要进一步的实验。

+0

'orderPropertyToTextViewId.forEach {属性,textViewId - > ...}'比依赖于'for'更多的功能(地道)代码循环 –

1

如果您不需要经常刷新新数据,则不需要保留对TextView的引用。我不使用安口,但它可能看起来像:

val order: Order = JSON.readValue(json!!) 
verticalLayout { 
    arrayOf(order.customer, order.address, order.postal_code, order.phone) 
      .map { 
       textView { 
        text = it 
       } 
      } 
} 
相关问题