Intereting Posts
Функция расширения Kotlin доступа к частному полю Java Как получить пакет kotlin путем отражения использование intellij-markdown в проекте kotlin android Как скомпилировать проект Java + Kotlin с использованием Maven? Тестирование блоков Kotlin coroutines с использованием mockito RxJava – Входы клавиатуры с обратным давлением? Как динамически масштабировать отскок потока эмиссионных выбросов? Почему я вынужден использовать !! в сочетании с нулевыми проверками? Ошибка «Расширение с именем» android «не существует» при добавлении проекта Kotlin в Android Фильтрация массива объектов по расстоянию Котлин OnClick и TextView в Android Studio 3 Как использовать привязку данных и Kotlin в Android Studio 3.0.0 Класс данных Kotlin: как читать значение свойства, если я не знаю его имени во время компиляции? Функция логарифма расширения Kotlin с logback (slf4j) Ленивая инициализация элемента с нулевым значением

Есть ли чистый DRY способ обновления нескольких текстовых элементов из HTTP-запроса JSON?

У меня есть следующие действия 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 } } } } 

Для яростной питонисты, такой как я, это кажется ужасно статическим и многословным способом сделать это.

Есть ли способ лучше?

Поскольку есть только TextView и вам нужно только изменить их текст, вы можете упростить свой код следующим образом:

  • Добавьте отображение свойств 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 { ... } вместо идентификаторов на карте, но это требует дальнейшего эксперимента ,

Если вам не нужно часто обновлять новые данные, вам не нужно сохранять ссылки на TextView . Я не использую Anko, но он может выглядеть так:

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