作为我的一门课程的一部分,我需要显示一个recyclerview,根据所选的品牌列出汽车型号。我设法在我的activity中检索到了品牌的id。但是,当我想把它发送到包含recyclerview的片段时,我得到了一个错误。截图如下。
这显然是来自我的supportFragmentManager在活动中,但我无法找到一个解决方案。如果有人能帮助我,这将是伟大的。
谢谢你
The error
主要活动2.kt
package ca.ulaval.ima.tp3
import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import ca.ulaval.ima.tp3.databinding.ActivityMain2Binding
class MainActivity2 : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMain2Binding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMain2Binding.inflate(layoutInflater)
setContentView(binding.root)
val idMarque = intent.getStringExtra("idMarque")
println(idMarque)
val fragment = ModèleFragment()
val bundle = Bundle()
bundle.putString("idmarque", idMarque)
fragment.arguments = bundle
supportFragmentManager.beginTransaction().replace(R.id.recyclerView_main, fragment).commit()
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
override fun onSupportNavigateUp(): Boolean {
onBackPressed()
return super.onSupportNavigateUp()
}
}
模块片段.kt
package ca.ulaval.ima.tp3
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import kotlinx.android.synthetic.main.fragment_marque_list.*
import okhttp3.*
import java.io.IOException
/**
* A fragment representing a list of Items.
*/
class ModèleFragment : Fragment(), OnModeleClickListener {
private var columnCount = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
columnCount = it.getInt(ARG_COLUMN_COUNT)
}
fetchJson()
}
fun fetchJson() {
val data = arguments
val idMarque = data?.get("idmarque")
val url = "https://tp3.infomobile.app/api/v1/brand/"+idMarque.toString()+"/models"
val request = Request.Builder().url(url).build()
val lesmodeles = OkHttpClient()
lesmodeles.newCall(request).enqueue(object: Callback {
override fun onResponse(call: Call, response: Response) {
val body = response.body?.string()
val gson = GsonBuilder().create()
val homeFeed = gson.fromJson(body, HomeFeedModele::class.java)
activity?.runOnUiThread {
recyclerView_main.adapter = MyModèleRecyclerViewAdapter(homeFeed)
}
}
override fun onFailure(call: Call, e: IOException) {
println("Failed to execute request")
}
})
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_modele_list, container, false)
// Set the adapter
if (view is RecyclerView) {
with(view) {
layoutManager = when {
columnCount <= 1 -> LinearLayoutManager(context)
else -> GridLayoutManager(context, columnCount)
}
//adapter = MyModèleRecyclerViewAdapter(listeDesVoitures)
}
}
return view
}
override fun onModeleItemClicked(position: Int) {
Toast.makeText(this.context, "ça marche", Toast.LENGTH_LONG).show()
val intent = Intent(this@ModèleFragment.requireContext(),MainActivity3::class.java)
startActivity(intent)
}
companion object {
// TODO: Customize parameter argument names
const val ARG_COLUMN_COUNT = "column-count"
// TODO: Customize parameter initialization
@JvmStatic
fun newInstance(columnCount: Int) =
ModèleFragment().apply {
arguments = Bundle().apply {
putInt(ARG_COLUMN_COUNT, columnCount)
}
}
}
}
class HomeFeedModele(
@SerializedName("content")
val modeles: List<Modele>
)
class Modele(
@SerializedName("id")
val id: Int,
@SerializedName("name")
val name: String
)
我的模块回收视图适配器
package ca.ulaval.ima.tp3
import android.content.Intent
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import ca.ulaval.ima.tp3.placeholder.PlaceholderContent.PlaceholderItem
import ca.ulaval.ima.tp3.databinding.FragmentModeleBinding
/**
* [RecyclerView.Adapter] that can display a [PlaceholderItem].
* TODO: Replace the implementation with code for your data type.
*/
class MyModèleRecyclerViewAdapter(val homeFeedModele: HomeFeedModele?
) : RecyclerView.Adapter<MyModèleRecyclerViewAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
FragmentModeleBinding.inflate(
LayoutInflater.from(parent.context),
parent,
false
)
)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = homeFeedModele?.modeles?.get(position)
val leModele = item?.name.toString()
holder.contentView.text = leModele
holder.contentView.setOnClickListener{
val context=holder.contentView.context
val intent = Intent( context, MainActivity3::class.java)
intent.putExtra("idModele", item?.id)
context.startActivity(intent)
}
}
override fun getItemCount(): Int {
return homeFeedModele?.modeles?.size ?: 0
}
inner class ViewHolder(binding: FragmentModeleBinding) : RecyclerView.ViewHolder(binding.root) {
val contentView: TextView = binding.content
override fun toString(): String {
return super.toString() + " '" + contentView.text + "'"
}
}
}
片段模型列表.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.recyclerview.widget.RecyclerView 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:id="@+id/recyclerView_main"
android:name="ca.ulaval.ima.tp3.ModèleFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
app:layoutManager="LinearLayoutManager"
tools:context=".ModèleFragment"
tools:listitem="@layout/fragment_modele" />
回答
我最终找到了一个解决方案,直接在Activity中使用我的API,而不需要遍历片段,也不需要使用bundle。
主要活动2.kt
package ca.ulaval.ima.tp3
import android.os.Bundle
import com.google.android.material.snackbar.Snackbar
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.navigateUp
import androidx.navigation.ui.setupActionBarWithNavController
import ca.ulaval.ima.tp3.databinding.ActivityMain2Binding
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import kotlinx.android.synthetic.main.fragment_marque_list.*
import okhttp3.*
import java.io.IOException
class MainActivity2 : AppCompatActivity() {
private lateinit var appBarConfiguration: AppBarConfiguration
private lateinit var binding: ActivityMain2Binding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMain2Binding.inflate(layoutInflater)
setContentView(binding.root)
fetchJson()
setSupportActionBar(binding.toolbar)
val navController = findNavController(R.id.nav_host_fragment_content_main)
appBarConfiguration = AppBarConfiguration(navController.graph)
setupActionBarWithNavController(navController, appBarConfiguration)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
}
fun fetchJson() {
//val data = arguments
val idMarque = intent.getStringExtra("idMarque")
println("id de la marque" + idMarque)
val url = "https://tp3.infomobile.app/api/v1/brand/"+idMarque.toString()+"/models"
val request = Request.Builder().url(url).build()
val lesmodeles = OkHttpClient()
lesmodeles.newCall(request).enqueue(object: Callback {
override fun onResponse(call: Call, response: Response) {
val body = response.body?.string()
val gson = GsonBuilder().create()
val homeFeed = gson.fromJson(body, HomeFeedModele::class.java)
runOnUiThread {
recyclerView_main.adapter = MyModèleRecyclerViewAdapter(homeFeed)
}
}
override fun onFailure(call: Call, e: IOException) {
println("Failed to execute request")
}
})
}
override fun onSupportNavigateUp(): Boolean {
onBackPressed()
return super.onSupportNavigateUp()
}
}
class HomeFeedModele(
@SerializedName("content")
val modeles: List<Modele>
)
class Modele(
@SerializedName("id")
val id: Int,
@SerializedName("name")
val name: String
)
模块片段.kt
package ca.ulaval.ima.tp3
import android.content.Intent
import android.os.Bundle
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import com.google.gson.GsonBuilder
import com.google.gson.annotations.SerializedName
import kotlinx.android.synthetic.main.fragment_marque_list.*
import okhttp3.*
import java.io.IOException
/**
* A fragment representing a list of Items.
*/
class ModèleFragment : Fragment(), OnModeleClickListener {
private var columnCount = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
columnCount = it.getInt(ARG_COLUMN_COUNT)
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_modele_list, container, false)
// Set the adapter
if (view is RecyclerView) {
with(view) {
layoutManager = when {
columnCount <= 1 -> LinearLayoutManager(context)
else -> GridLayoutManager(context, columnCount)
}
//adapter = MyModèleRecyclerViewAdapter(listeDesVoitures)
}
}
return view
}
override fun onModeleItemClicked(position: Int) {
Toast.makeText(this.context, "ça marche", Toast.LENGTH_LONG).show()
val intent = Intent(this@ModèleFragment.requireContext(),MainActivity3::class.java)
startActivity(intent)
}
companion object {
// TODO: Customize parameter argument names
const val ARG_COLUMN_COUNT = "column-count"
// TODO: Customize parameter initialization
@JvmStatic
fun newInstance(columnCount: Int) =
ModèleFragment().apply {
arguments = Bundle().apply {
putInt(ARG_COLUMN_COUNT, columnCount)
}
}
}
}
1条答案
按热度按时间mv1qrgav1#
当你从Json解析body响应时,错误就在第50行,它可以是空的。请检查以下方法:
val body = response.body?.string()
上设置一个断点并检查其值。如果它继续失败,请在评论中分享json的回应,我会尽力帮助你。