Kotlin使用Retrofit请求国家列表后Spinner仅显示国家名称如何实现
Spinner显示异常问题解决方案
当前异常显示效果如下:
问题根因
系统自带的ArrayAdapter默认会调用列表中每个元素的toString()方法渲染文本,你传入的是自定义数据类集合,Kotlin数据类默认的toString()会输出包含类名、所有属性的格式化内容,因此出现上述异常显示效果。
可选解决方案
方案一:提取国家名称列表传入适配器(无需修改其他文件,实现最快)
修改MainActivity.kt中适配器初始化逻辑,先从接口返回的数据中提取所有国家的通用名称,生成字符串列表再传给适配器:
val apiInterface = ApiInterface.create().getCountry() apiInterface.enqueue( object : Callback<List<data>>{ override fun onResponse(call: Call<List<data>>?, response: Response<List<data>>?) { if(response?.body() != null){ // 新增:提取所有国家的通用名称 val countryNameList = response.body()!!.map { it.name.common } val adapter = ArrayAdapter(this@MainActivity,android.R.layout.simple_spinner_item, countryNameList) binding.spCountry.adapter=adapter } } override fun onFailure(call: Call<List<data>>?, t: Throwable?) {} })
方案二:重写数据类的toString()方法(适配性更强,后续需用到数据类其他属性时推荐)
首先修改data.kt文件,重写数据类的toString方法返回国家通用名,同时建议修改类名避免和Kotlin的data关键字冲突,符合命名规范:
// 将原data类重命名为Country,避免和Kotlin关键字冲突 data class Country( @SerializedName("name") val name: CountryName ) { // 重写toString方法,直接返回国家通用名 override fun toString(): String { return name.common } } // 同步将原name类重命名为CountryName data class CountryName( @SerializedName("common") val common: String )
使用该方案需同步修改MainActivity.kt和ApiInterface.kt中所有List<data>的引用,替换为List<Country>即可,原有适配器初始化逻辑无需修改。
额外注意事项
你当前ApiInterface.kt中的BASE_URL配置存在路径拼接错误风险,建议调整为规范写法:
interface ApiInterface { // 去掉路径开头的/,使用相对路径 @GET("v3.1/all") fun getCountry() : Call<List<Country>> companion object { // BASE_URL改为根域名,结尾保留/ var BASE_URL = "https://restcountries.com/" fun create() : ApiInterface { val retrofit = Retrofit.Builder() .addConverterFactory(GsonConverterFactory.create()) .baseUrl(BASE_URL) .build() return retrofit.create(ApiInterface::class.java) } } }
内容的提问来源于stack exchange,提问作者Victor Escalante
相关产品推荐
相关产品推荐

