2017-02-15 12 views
1

У меня есть следующие действия Kotlin/Anko/Android.Есть ли чистый DRY способ обновления нескольких текстовых элементов из HTTP-запроса JSON?

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 свойства хранения идентификаторов:

    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) 
    } 
    

Вы можете пойти еще дальше и избавиться от идентификаторов и findViewById<TextView>(...), если вы храните TextView, возвращаемых 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 
       } 
      } 
}