gpt4 book ai didi

java - 为什么 RecyclerView 在其他 Kotlin Android 之前加载

转载 作者:行者123 更新时间:2023-12-05 04:30:39 25 4
gpt4 key购买 nike

你好,我正在为我的作业做一个小应用程序,我想在应用程序上显示来 self 的 php api 的数据。但是 Recycler View 发送此消息 2022-04-25 00:41:36.662 13593-13593/net.robcorp.finalapp E/RecyclerView: 没有连接适配器;在适配器代码运行之前跳过布局,因为此消息 2022-04-25 00:41:36.907 13593-13593/net.robcorp.finalapp I/System.out: [Drivers(pos=1, name =Charles Leclerc, nb=16, points=71, title=Ferrari), Drivers(pos=2, name=Esteban Ocon, nb=31, points=20, title=Alpine)] 显示在上一个之后一个并且假设在适配器之前运行。这是 DriversFragment.kt:

package net.robcorp.finalapp

import android.content.Context
import android.graphics.Insets.add
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.OneShotPreDrawListener.add
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.android.volley.Request
import com.android.volley.Response
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import net.robcorp.finalapp.R
import net.robcorp.finalapp.databinding.FragmentDriversBinding
import net.robcorp.finalapp.drivers.DriverFragmentAdapter
import net.robcorp.finalapp.drivers.Drivers
import org.json.JSONArray


class DriversFragment : Fragment(R.layout.fragment_drivers) {

private lateinit var recyclerView: RecyclerView
private lateinit var myAdapter: DriverFragmentAdapter;
lateinit var binding: FragmentDriversBinding
private val drivers = ArrayList<Drivers>()
val url = "https://robcorp.net/f1api/getdrivers.php"

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentDriversBinding.inflate(layoutInflater)
recyclerView = binding.driversRecyclerView
recyclerView.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
myAdapter = DriverFragmentAdapter(drivers)
recyclerView.adapter = myAdapter
println("adapter loaded")
downloadDrivers()
}

fun downloadDrivers() {
val task = Volley.newRequestQueue(this.context)
val request = StringRequest(Request.Method.GET, url, {
response ->
val data = response.toString()
val jArray = JSONArray(data)
// Log.e("Error",response.toString())
for (i in 0..jArray.length()-1) {
val json_data = jArray.getJSONObject(i)
// Log.e("Jobject",json_data.toString())
val pos = i+1
val name = json_data.getString("Name")
val nb = json_data.getString("NB")
val points = json_data.getString("Points")
val title = json_data.getString("Title")
val driver = Drivers(pos, name, nb, points, title)
drivers.add(driver)

}
println(drivers)
myAdapter.notifyDataSetChanged()
}, {
error ->
println(error)
})
task.add(request)
}
}

这是 DriverFragmentAdapter.kt:

package net.robcorp.finalapp.drivers

import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import net.robcorp.finalapp.R
import net.robcorp.finalapp.databinding.DriverListBinding

class DriverFragmentAdapter(private var driversList: List<Drivers>): RecyclerView.Adapter<DriverFragmentAdapter.MyViewHolder>() {

class MyViewHolder(val binding: DriverListBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(driver: Drivers) {
val context = itemView.context
val pos = itemView.findViewById<TextView>(R.id.driver_position)
val bar = itemView.findViewById<TextView>(R.id.driver_bar)
val name = itemView.findViewById<TextView>(R.id.driver_name)
val nb = itemView.findViewById<TextView>(R.id.driver_number)
val team = itemView.findViewById<TextView>(R.id.driver_team)
val points = itemView.findViewById<TextView>(R.id.driver_points)

pos.text = driver.pos.toString()
name.text = driver.name
nb.text = driver.nb
team.text = driver.title
points.text = driver.points

if (driver.title == "Ferrari") {
bar.background = ContextCompat.getDrawable(context, R.drawable.ferrari_bar)
} else if (driver.title == "Alpine") {
bar.background = ContextCompat.getDrawable(context, R.drawable.alpine_bar)
} else if (driver.title == "Red Bull") {
bar.background = ContextCompat.getDrawable(context, R.drawable.redbull_bar)
} else if (driver.title == "Mercedes") {
bar.background = ContextCompat.getDrawable(context, R.drawable.mercedes_bar)
} else if (driver.title == "McLaren") {
bar.background = ContextCompat.getDrawable(context, R.drawable.mclaren_bar)
} else if (driver.title == "Alfa Romeo") {
bar.background = ContextCompat.getDrawable(context, R.drawable.alfaromeo_bar)
} else if (driver.title == "AlphaTauri") {
bar.background = ContextCompat.getDrawable(context, R.drawable.alphatauri_bar)
} else if (driver.title == "Williams") {
bar.background = ContextCompat.getDrawable(context, R.drawable.williams_bar)
} else if (driver.title == "Aston Martin") {
bar.background = ContextCompat.getDrawable(context, R.drawable.astonmartin_bar)
} else if (driver.title == "Haas") {
bar.background = ContextCompat.getDrawable(context, R.drawable.haas_bar)
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
return MyViewHolder(DriverListBinding.inflate(LayoutInflater.from(parent.context)))

}

override fun getItemCount(): Int {
return driversList.size
}

override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
val driver = driversList[position]
holder.binding.apply {
println("je suis dans le binding")
holder.bind(driver)
}
}

fun setDriversList(driversList: List<Drivers>) {
this.driversList = driversList
notifyDataSetChanged()
}

}

fragment 驱动程序.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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=".MainActivity">

<!-- TODO: Update blank fragment layout -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<LinearLayout
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/primary"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="10dp">

<TextView
android:id="@+id/calendar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="30dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="30dp"
android:layout_marginBottom="20dp"
android:fontFamily="@font/marianneb"
android:text="Pilotes"
android:textAlignment="center"
android:textColor="@color/white"
android:textSize="25sp" />

</LinearLayout>

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/drivers_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="@+id/header"/>

</LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

驱动程序列表.xml

<?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"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="10dp"
android:layout_marginEnd="20dp"
android:elevation="8dp"
android:orientation="horizontal"
android:padding="10dp"
android:background="@drawable/rectangle">

<TextView
android:id="@+id/driver_position"
android:layout_width="30dp"
android:layout_height="match_parent"
android:fontFamily="@font/marianneb"
android:text="1"
android:textColor="@color/black"
android:textSize="25sp"
android:textAlignment="center"/>

<ImageView
android:id="@+id/driver_bar"
android:layout_width="20px"
android:layout_height="match_parent"
android:background="@drawable/ferrari_bar"/>



<LinearLayout
android:layout_width="250dp"
android:layout_height="wrap_content"
android:orientation="vertical">

<TextView
android:id="@+id/driver_name"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fontFamily="@font/marianneb"
android:text="Charles Leclerc"
android:textColor="@color/black"
android:textSize="15sp"
android:layout_marginStart="10dp"/>

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

<TextView
android:id="@+id/driver_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="2.5dp"
android:fontFamily="@font/mariannem"
android:text="16"
android:textColor="@color/black"
android:textSize="10sp" />

<TextView
android:id="@+id/driver_team"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="2.5dp"
android:fontFamily="@font/mariannem"
android:text="Ferrari"
android:textColor="@color/black"
android:textSize="10sp" />

</LinearLayout>

</LinearLayout>

<TextView
android:id="@+id/driver_points"
android:layout_width="50dp"
android:layout_height="match_parent"
android:fontFamily="@font/marianneb"
android:text="578"
android:textColor="@color/black"
android:textSize="25sp"/>



</LinearLayout>

最佳答案

这是一个无害的警告。由于您的 RecyclerView 已经在布局中,它会在您的 View 层次结构可见时尝试绘制它,发现没有分配适配器,因此它只是发出警告而不绘制它。

也许创建您的适配器(使用空列表)并在膨胀 View 时立即分配它,并在数据准备好时更新其列表可能会更干净。

顺便说一下,在onCreate 中膨胀你的布局是不正确的。这应该在 onCreateView 中完成。


编辑:

此处的代码将布局膨胀两次,一次用于变量 v,一次用于 binding 属性。首先,没有理由给它充气两次。其次,由于您使用 v 作为 onCreateView 的返回值,因此您对 binding 中的 View 所做的任何操作都是毫无意义的,对实际显示在屏幕上的 View 。

    val v = inflater.inflate(R.layout.fragment_drivers, container, false)
binding = FragmentDriversBinding.inflate(layoutInflater)
// ...
return v

您应该只膨胀一次 View (使用绑定(bind))并返回绑定(bind)的 View :

    // DELETE THIS LINE: val v = inflater.inflate(R.layout.fragment_drivers, container, false)
binding = FragmentDriversBinding.inflate(layoutInflater)
// ...
return binding.root

此外,在 onViewCreated() 中设置 View 比在 onCreateView() 中设置 View 更合适。如果这样做,您实际上可以通过将 View ID 传递给 Fragment 构造函数,将膨胀转移到 super 构造函数调用中,然后绑定(bind)到现有 View 而不是膨胀绑定(bind)。它看起来像这样:

class DriversFragment : Fragment(R.layout.fragment_drivers) {

private lateinit var recyclerView: RecyclerView
private lateinit var myAdapter: DriverFragmentAdapter;
lateinit var binding: FragmentDriversBinding
private val drivers = ArrayList<Drivers>()
val url = "https://robcorp.net/f1api/getdrivers.php"

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentDriversBinding.bind(view)
recyclerView = binding.driversRecyclerView

recyclerView.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)

myAdapter = DriverFragmentAdapter(drivers)

recyclerView.adapter = myAdapter
println("adapter loaded")
downloadDrivers()
}

//...
}

关于java - 为什么 RecyclerView 在其他 Kotlin Android 之前加载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71992973/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com