【问题标题】:Is there a clean DRY way to update multiple textViews from HTTP request JSON?是否有一种干净的 DRY 方法可以从 HTTP 请求 JSON 更新多个 textView?
【发布时间】:2017-02-15 08:39:26
【问题描述】:

我有以下 Kotlin / Anko / Android 活动。

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

对于像我这样顽固的 Python 达人来说,这似乎是一种非常静态和冗长的做法。

有没有更好的办法?

【问题讨论】:

    标签: json kotlin anko


    【解决方案1】:

    由于只有TextViews,您只需更改其文本,您可以通过以下方式简化代码:

    • 为存储 ID 的 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)
      }
      

    如果您将textView { ... } 调用返回的TextViews 而不是映射中的ID 存储在地图中,您可以更进一步,摆脱ID 和findViewById&lt;TextView&gt;(...),但这需要进一步试验。

    【讨论】:

    • orderPropertyToTextViewId.forEach { property, textViewId -&gt; ... } 获得比依赖 for 循环更实用(和惯用)的代码
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-14
      • 2022-01-08
      • 1970-01-01
      • 1970-01-01
      • 2015-03-03
      • 2010-09-12
      • 1970-01-01
      相关资源
      最近更新 更多