I'm retrieving a list of lists from an API in JSON. This is how the response looks like.
{
"result":"success",
"documentation":"https://www.exchangerate-api.com/docs",
"terms_of_use":"https://www.exchangerate-api.com/terms"
"supported_codes":[
["AED","UAE Dirham"],
["AFN","Afghan Afghani"],
["ALL","Albanian Lek"],
["AMD","Armenian Dram"],
["ANG","Netherlands Antillian Guilder"],
["AOA","Angolan Kwanza"],
["ARS","Argentine Peso"],
["AUD","Australian Dollar"],
["AWG","Aruban Florin"],
["AZN","Azerbaijani Manat"],
["BAM","Bosnia and Herzegovina Convertible Mark"],
["BBD","Barbados Dollar"] etc. etc.
]
}
And this is the data class
data class CurrencyResponse(
@Json(name="documentation") val documentation: String,
@Json(name="result") val result: String,
@Json(name="supported_codes") val supported_codes: List<List<String>>,
@Json(name="terms_of_use") val terms_of_use: String
)
I managed to get the list of lists(supported_codes) but what I want now is to get the first index of each list(AED,AFN,ALL,etc.) and store them in a list, convert it to an array, then use that array to populate my spinners. Can anyone help me out with that?
Below is the relevant code.
Thank you.
CurrencyRepository.kt
package com.example.currencyconverter.data
import com.example.currencyconverter.BuildConfig
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class CurrencyRepository @Inject constructor(private val currencyApi: CurrencyApi) {
suspend fun getConversionRate(baseCurrency: String, toCurrency: String, amount: Double?): ConversionResponse {
return currencyApi.convert(BuildConfig.API_KEY, baseCurrency, toCurrency, amount)
}
suspend fun getCurrencies(): List<String> {
return currencyApi.getCurrencies(BuildConfig.API_KEY).supported_codes
}
}
CurrencyViewModel.kt
package com.example.currencyconverter.ui
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.example.currencyconverter.data.CurrencyRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class CurrencyViewModel @Inject constructor(private val repository: CurrencyRepository): ViewModel() {
private val _conversionResult = MutableLiveData<String>()
val conversionResult: LiveData<String> = _conversionResult
private val _currencies = MutableLiveData<List<String>>()
val currencies: LiveData<List<String>> = _currencies
init {
getCurrencies()
}
fun getConversionRate(baseCurrency: String, toCurrency: String, amount: Double?) {
viewModelScope.launch {
_conversionResult.value = repository.getConversionRate(baseCurrency, toCurrency, amount).conversion_result
}
}
fun getCurrencies() {
viewModelScope.launch {
_currencies.value = repository.getCurrencies()
}
}
}
HomeFragment.kt
package com.example.currencyconverter.ui
import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import android.widget.AdapterView
import android.widget.ArrayAdapter
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import com.example.currencyconverter.R
import com.example.currencyconverter.databinding.FragmentHomeBinding
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class HomeFragment : Fragment(R.layout.fragment_home) {
private val viewModel by viewModels<CurrencyViewModel>()
private var _binding: FragmentHomeBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_home, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
_binding = FragmentHomeBinding.bind(view)
lateinit var firstCurrency: String
lateinit var secondCurrency: String
viewModel.currencies.observe(viewLifecycleOwner) {
binding.list.text = " ${it[0]} , ${it[1]} "
}
var currenciesFormat = arrayOf(viewModel.currencies.value?.get(0),
viewModel.currencies.value?.get(1)
)
binding.apply {
spinnerFirst.adapter = ArrayAdapter(requireContext(), android.R.layout.simple_spinner_item, currenciesFormat)
spinnerFirst.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
adapterView: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
firstCurrency = adapterView?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
spinnerSecond.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
adapterView: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
secondCurrency = adapterView?.getItemAtPosition(position).toString()
}
override fun onNothingSelected(p0: AdapterView<*>?) {
}
}
}
binding.constraintLayout.setOnTouchListener(object : View.OnTouchListener {
override fun onTouch(p0: View?, p1: MotionEvent?): Boolean {
closeKeyboard(p0)
return true
}
})
binding.button.setOnClickListener {
val stringInTextField = binding.amountText.text.toString()
val amount = stringInTextField.toDoubleOrNull()
if (amount == null) {
binding.resultText.text = " "
}
closeKeyboard(binding.amountText)
viewModel.getConversionRate(firstCurrency, secondCurrency, amount)
viewModel.conversionResult.observe(viewLifecycleOwner) {
binding.resultText.text = it
}
}
}
private fun closeKeyboard(view: View?) {
val imm =
view?.context?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
if (view != null) {
imm.hideSoftInputFromWindow(view.windowToken, 0)
}
}
}
CodePudding user response:
You can use kotlin.collections
's map
function. https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map.html
fun main(){
val supportedCodes = listOf(
listOf("AED","UAE Dirham"),
listOf("AFN","Afghan Afghani"),
listOf("ALL","Albanian Lek")
)
val codes = supportedCodes.map { it[0] }
println(codes)
}
The output is a list containing just the first element from each nested list.
[AED, AFN, ALL]