是否有一种干净的 DRY 方法可以从 HTTP 请求 JSON 更新多个 textView?
Is there a clean DRY way to update multiple textViews from HTTP request JSON?
我有以下 Kotlin / Anko / Android activity.
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 来说,这样做似乎非常静态和冗长。
有没有更好的方法?
因为只有TextView
,你只需要改变他们的文本,你可以通过以下方式简化你的代码:
为存储 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 { ... }
调用返回的 TextView
而不是地图中的 ID,您可以更进一步删除 ID 和 findViewById<TextView>(...)
,但是这需要进一步试验。
如果您不需要经常刷新新数据,则不需要保留对 TextView
的引用。我不使用 Anko,但它可能看起来像:
val order: Order = JSON.readValue(json!!)
verticalLayout {
arrayOf(order.customer, order.address, order.postal_code, order.phone)
.map {
textView {
text = it
}
}
}
我有以下 Kotlin / Anko / Android activity.
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 来说,这样做似乎非常静态和冗长。
有没有更好的方法?
因为只有TextView
,你只需要改变他们的文本,你可以通过以下方式简化你的代码:
为存储 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 { ... }
调用返回的 TextView
而不是地图中的 ID,您可以更进一步删除 ID 和 findViewById<TextView>(...)
,但是这需要进一步试验。
如果您不需要经常刷新新数据,则不需要保留对 TextView
的引用。我不使用 Anko,但它可能看起来像:
val order: Order = JSON.readValue(json!!)
verticalLayout {
arrayOf(order.customer, order.address, order.postal_code, order.phone)
.map {
textView {
text = it
}
}
}