【问题标题】:How to display data in RecyclerView using Retrofit2 API?如何使用 Retrofit2 API 在 RecyclerView 中显示数据?
【发布时间】:2017-12-22 20:22:06
【问题描述】:

首先,我是 Android/Java/Kotlin 开发的新手。我正在使用 Retrofit2 从 Udacity API 检索数据。我可以在 Logcat 中看到响应,但是当我尝试在 RecyclerView 中显示它时,只有一个空白屏幕。我认为错误出在 MainActivity 中,但我仍然一无所知,需要帮助。

我的模型类

class Course(var title: String,
             var subtitle: String,
             var key: String,
             var instructors: List<Instructor>,
             var expected_learning: String,
             var required_knowledge: String)


class Instructor(var name: String,
                 var bio: String)

我的界面

interface ApiServiceInterface {

@GET("courses")
fun list() : Call<UdacityCatalog>

}

我的适配器

class CourseAdapter(val listCourses: ArrayList<Course?>, val context: Context) : RecyclerView.Adapter<CourseAdapter.CourseViewHolder>() {

    class CourseViewHolder(viewItem: View) : RecyclerView.ViewHolder(viewItem) { 
        val courseTitle = viewItem.findViewById<TextView?>(R.id.tv_title) as TextView 
        val courseSubtitle = viewItem.findViewById<TextView?>(R.id.tv_subtitle) as TextView 
        val courseKey = viewItem.findViewById<TextView?>(R.id.tv_course_key) as TextView 
        val instructorName = viewItem.findViewById<TextView?>(R.id.tv_instructor_name) as TextView 
    }

    override fun onCreateViewHolder(parent: ViewGroup?, viewType: Int): CourseViewHolder { 
        val viewHolder = LayoutInflater.from(parent?.context).inflate(R.layout.activity_item_list, parent, false) 
        val itemViewHolder = CourseViewHolder(viewHolder)
        return itemViewHolder
    }

    override fun onBindViewHolder(holder: CourseViewHolder?, position: Int) {
        holder?.courseTitle?.text = listCourses[position].title
        holder?.courseSubtitle?.text = listCourses[position].subtitle
        holder?.courseKey?.text = listCourses[position].key
        holder?.instructorName?.text = listCourses[position].instructors.toString() 
    }

    override fun getItemCount(): Int = listCourses.size

}

我的 MainActivity -- 我认为错误在这里,但我还没有弄清楚

class MainActivity : AppCompatActivity() {

    internal val TAG = "Testing Retrofit2 API"
    lateinit var mRecyclerView: RecyclerView
    lateinit var mCourseAdapter: RecyclerView.Adapter<CourseAdapter.CourseViewHolder>
    val listCourse = arrayListOf<Course?>()

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

        mRecyclerView = findViewById<RecyclerView?>(R.id.id_recycler_view) as RecyclerView

        val mLayoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)

        mRecyclerView.layoutManager = mLayoutManager

        mRecyclerView.setHasFixedSize(true)

        mCourseAdapter = CourseAdapter(listCourse, applicationContext)

        mRecyclerView.adapter = mCourseAdapter

        mCourseAdapter.notifyDataSetChanged()

        val call = RetrofitInitializer().createService().list()

        call.enqueue(object : Callback<UdacityCatalog> {

            override fun onResponse(call: Call<UdacityCatalog>, response: Response<UdacityCatalog>) {

                response.body()

                if (!response.isSuccessful) {
                    Log.i(TAG, "[ ERROR ] " + response.code())

                } else {

                    if (listCourse.isEmpty()) {
                        Toast.makeText(applicationContext, "Empty list!", Toast.LENGTH_LONG).show()
                    } else {
                        Toast.makeText(applicationContext, "Full list!", Toast.LENGTH_LONG).show()
                    }

                    val catalog = response.body()

                    for (c in catalog!!.courses!!) {
                        Log.i(TAG, String.format("%s: %s", c.title, c.subtitle, c.key, c.required_knowledge, c.expected_learning))

                        for (i in c.instructors!!) {
                            Log.i(TAG, i.name)
                        }
                        Log.i(TAG, "\n****************************************************************************************************\n")
                    }
                }
            }

            override fun onFailure(call: Call<UdacityCatalog>?, t: Throwable?) {
                Log.d(TAG, "onFailure() : " + t?.message)
            }

        })

    }

}

Retrofit 实例的初始化类

class RetrofitInitializer {

    companion object Factory {
        val BASE_URL = "https://www.udacity.com/public-api/v0/"
    }

    private val retrofit = Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build()

    fun createService(): ApiServiceInterface = retrofit.create(ApiServiceInterface::class.java)

}

我的 RecyclerView xml 文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingBottom="16dp"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    tools:context="activities.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/id_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

    </android.support.v7.widget.RecyclerView>

</LinearLayout>

我的 CardView xml 文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="16dp"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="16dp"
        android:paddingLeft="16dp"
        android:paddingRight="16dp"
        android:paddingTop="16dp">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@string/udacity_catalog"
            android:textAppearance="?android:textAppearanceLarge"
            android:textColor="#9C27B0"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:gravity="start"
            android:hint="@string/hint_title"
            android:textAppearance="?android:textAppearanceMedium"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/tv_subtitle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:gravity="start"
            android:hint="@string/hint_subtitle"
            android:textAppearance="?android:textAppearanceMedium"
            android:textColor="#000000" />

        <TextView
            android:id="@+id/tv_course_key"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="20dp"
            android:gravity="start"
            android:hint="@string/hint_key"
            android:textAppearance="?android:textAppearanceMedium"
            android:textColor="#000000" />

        <TextView
           android:id="@+id/tv_instructor_name"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:layout_marginTop="20dp"
           android:gravity="start"
           android:hint="@string/hint_name"
           android:textAppearance="?android:textAppearanceMedium"
           android:textColor="#000000" />

    </LinearLayout>

</android.support.v7.widget.CardView>

【问题讨论】:

  • 您是否正在将检索到的数据传递给您的适配器?我看不到你这样做。

标签: android android-recyclerview kotlin retrofit2 recyclerview-layout


【解决方案1】:

您的Activity 中有一个空的课程列表 (listCourse)。您通过它的构造函数将该空列表传递给适配器。 即使在您获取课程后,该列表仍为空。所以适配器 /RecyclerView 保持为空。

尝试在您获取课程之后创建适配器,使用

  mCourseAdapter = CourseAdapter(catalog!!.courses!!, applicationContext)

或者在你的适配器里有一个课程属性

YourAdapter(...) {
    var courses = listOf(Course)
}

然后在您的Activity 中(获取课程后):

adapter.courses = catalog!!.courses!!
adapter.notifyDataSetChanged()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    • 2019-05-31
    • 2019-08-20
    相关资源
    最近更新 更多