通过改造和moshi填充旋转器

时间:2017-12-06 13:35:22

标签: android json kotlin retrofit2 moshi

我是android dev(java或kotlin)的初学者。我试图通过改装和moshi从json填充微调器,但我不知道如何将它填充到微调器中。说实话,我不知道Json数据的返回是否正确,因为Log.d()返回不是详细的dump()laravel或php。

活动onCreate中的

脚本(请阅读脚本的注释,我将Log.d()的调试结果放在那里):

val task = object : AsyncTask<Void, Void, Response<List<ProductTypeResponse>>>() {
        override fun doInBackground(vararg params: Void): Response<List<ProductTypeResponse>> {

            val typeAPI = RestAPI()
            val callResponse = typeAPI.getNews()
            val response = callResponse.execute()

            return response

        }

        override fun onPostExecute(response: Response<List<ProductTypeResponse>>) {
            if (response.isSuccessful) {
                val news = response.body()
                Log.d("test:", news!![0].data.toString()) //  method 'java.lang.String com.example.mockie.tigaer.api.TypeDataResponse.toString()' on a null object reference
                Log.d("test:", news!!.size.toString()) // it says 67 but the data from the url is 63 array of json object
                Log.d("test:", news!![0].toString()) // com.example.mockie.tigaer.api.ProductTypeResponse@f17fd5e
            }
        }

RestApi.kt

import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory

class RestAPI() {

private val tigaerApi: TigaerApi

init {
    val retrofit = Retrofit.Builder()
            .baseUrl("http://app.tigaer.id/laravel/")
            .addConverterFactory(MoshiConverterFactory.create())
            .build()

    tigaerApi = retrofit.create(TigaerApi::class.java)
}

fun getNews(): Call<List<ProductTypeResponse>> {
    return tigaerApi.getTop()
}
}

ApiModel.kt

package com.example.mockie.tigaer.api

class ProductTypeResponse(val data: TypeDataResponse)

class TypeDataResponse(
    val children: List<ProductTypeChildrenResponse>
 )

 class ProductTypeChildrenResponse(val data: ProductTypeDataResponse)

 class ProductTypeDataResponse(
    val productType: String,
    val readable: String
 )

TigaerApi.kt

import retrofit2.Call
import retrofit2.http.GET
import retrofit2.http.Query

interface  TigaerApi {
@GET("api/type")
fun getTop(): Call<List<ProductTypeResponse>>
}

返回Json:https://jsoneditoronline.org/?id=ce90c41b859218e746e41d64eddb4c30

所以我的问题是:

  1. 是否有任何调试对象/数组的功能,如laravel中的详细信息一样?
  2. 如何将我的json返回数据填充到spinner中?

3 个答案:

答案 0 :(得分:1)

以下是相同的代码,我修改并仅在您的代码中集成:

“MainActivity.kt”类:

 class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    var spinner: Spinner = findViewById(R.id.spinner)

    val task = object : AsyncTask<Void, Void, Response<List<ProductTypeDataResponse>>>() {
        override fun doInBackground(vararg params: Void): Response<List<ProductTypeDataResponse>> {

            val typeAPI = RestAPI()
            val callResponse = typeAPI.getNews()
            val response = callResponse.execute()

            return response

        }

        override fun onPostExecute(response: Response<List<ProductTypeDataResponse>>) {
            if (response.isSuccessful) {
                val news: List<ProductTypeDataResponse>? = response.body()

                var adapter: SpinnerAdapter = SpinnerAdapter(this@MainActivity, news!!);

                spinner.adapter=adapter


               }
        }
    }.execute()
}
}

现在布局“activity_main”:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ankitpatidar.checkkotlin.MainActivity">

<Spinner
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/spinner"></Spinner>
</LinearLayout>

现在Spinner适配器为“SpinnerAdapter”:

 class SpinnerAdapter internal constructor(internal var context: Context, internal var list: List<ProductTypeDataResponse>) : BaseAdapter() {
override fun getCount(): Int {
    return list.size
}

override fun getItem(i: Int): Any? {
    return null
}

override fun getItemId(i: Int): Long {
    return 0
}

override fun getView(i: Int, view: View?, viewGroup: ViewGroup): View {
    var view = view
    if (view == null) {
        val inflater = LayoutInflater.from(context)

        view = inflater.inflate(R.layout.item, viewGroup, false)
    }

    val textView = view!!.findViewById<TextView>(R.id.textView)

    textView.text = list[i].productType + " " + list[i].readable

    return textView

}
}

微调项目布局为“项目”:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/textView"/>

</LinearLayout>

现在对现有文件进行了一些更改:

<强> “ApiModel.kt”:

 class TypeDataResponse(
    val children: List<ProductTypeChildrenResponse>
 )

 class ProductTypeChildrenResponse(val data: ProductTypeDataResponse)

 class ProductTypeDataResponse(
    val productType: String,
    val readable: String
 )

<强> “RestAPI.kt”

 class RestAPI() {

private val tigaerApi: TigaerApi

init {
    val retrofit = Retrofit.Builder()
            .baseUrl("http://app.tigaer.id/laravel/")
            .addConverterFactory(MoshiConverterFactory.create())
            .build()

    tigaerApi = retrofit.create(TigaerApi::class.java)
}

fun getNews(): Call<List<ProductTypeDataResponse>> {
    return tigaerApi.getTop()
}
}

因此它会对你有用。

答案 1 :(得分:0)

  

是否有任何函数来调试对象/数组的详细信息,如laravel?

通过此操作以在调试模式下运行您的应用。 https://developer.android.com/studio/debug/index.html

在应用程序运行时,您始终可以使用断点来计算表达式。而不是记录在这一行放置一个断点。

 val news = response.body()

因此,当您收到服务器的回复时,应用会在此时停止,您可以详细检查您的回复。

  

如何将我的json返回数据填充到微调器中?

如果您从Json格式的服务器获得响应,如提供的链接所示,您必须将数据解析为对象列表(POJO)。 然后你必须转发这些数据(可能你必须遍历列表来获取所需的数据,因为每个对象中有两个字段)到适配器中并将该适配器设置为你的微调器。在以下链接中可以非常清楚地解释。 https://developer.android.com/guide/topics/ui/controls/spinner.html

答案 2 :(得分:0)

我在这篇文章中有了一个主意,也许我的逻辑可以帮助这里的任何人

这是我的JSON

{
"success": 1,
"dataset": [
    {
        "id": "3",
        "nama": "Rush"
    },
    {
        "id": "5",
        "nama": "Avanza"
    },
    {
        "id": "6",
        "nama": "Innova"
    },
    {
        "id": "14",
        "nama": "Sienta"
    },
    {
        "id": "15",
        "nama": "Alphard"
    },
    {
        "id": "16",
        "nama": "Calya"
    }
],
"sql_duration": 0.0013179779052734375,
"auth_duration": 1.9073486328125e-6,
"req_duration": 0.004480123519897461,
"debug_duration": []
}

这是我的API服务

ApiMain.kt

class ApiMain : Application(){
private var BASE_URL = "your url in here"

private val client = OkHttpClient().newBuilder()
    .addInterceptor(HttpLoggingInterceptor().apply {
        level = if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
    })
    .readTimeout(30, TimeUnit.SECONDS)
    .writeTimeout(30, TimeUnit.SECONDS)
    .build()
private val retrofit = Retrofit.Builder()
    .baseUrl(BASE_URL)
    .client(client)
    .addConverterFactory(GsonConverterFactory.create())
    .build()
val services: ApiServices = retrofit.create(ApiServices::class.java)
}

这是我的API服务

ApiServices.kt

interface ApiServices {
    @GET("yourlink")
    fun MerkKendaraan():Call<MerkKendaraan>
}

这是我的模特

kendaraan.kt

data class MerkKendaraan(
@SerializedName("success")
@Expose
var success: Int? = null,

@SerializedName("dataset")
@Expose
var dataset: List<MerkMobil>? = null,

@SerializedName("sql_duration")
@Expose
var sql_duration: String? = null,

@SerializedName("auth_duration")
@Expose
var auth_duration: String? = null,

@SerializedName("req_duration")
@Expose
var req_duration: String? = null

)

data class MerkMobil(
    @SerializedName("id")
    @Expose
    var id: String? = null,

    @SerializedName("nama")
    @Expose
    var nama: String? = null
)

这是我的主要活动

添加肯达拉语

class AddKendaraan : AppCompatActivity() {

private var merk : ArrayList<MerkMobil> = ArrayList()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_add_kendaraan)
    configspinnermobil()
}

private fun configspinnermobil() {
    val spinner: Spinner = findViewById(R.id.spinnerMerk)

    ApiMain().services.MerkKendaraan().enqueue(object :
        Callback<MerkKendaraan> {
        override fun onResponse(call: Call<MerkKendaraan>, response: Response<MerkKendaraan>) {
            //Tulis code jika response sukses
            Log.d("data api", "data masuk")
            if(response.code() == 200){
                    merk = response.body()?.dataset as ArrayList<MerkMobil>
                var data : MutableList<String> = ArrayList()
                merk.forEach {
                    data.add(0,it.nama.toString())
                }
                spinner.adapter = ArrayAdapter<String>(this@AddKendaraan, R.layout.support_simple_spinner_dropdown_item, data)
            }else{

            }

        }
        override fun onFailure(call: Call<MerkKendaraan>, t: Throwable){
            //Tulis code jika response fail
            Toast.makeText(applicationContext, t.message, Toast.LENGTH_LONG).show()
            Log.d("data api", "data tidak masuk")

        }
    })
}