8 votes

J'essaie de créer un simple recyclerView en Kotlin, mais l'adaptateur ne s'applique pas correctement.

J'essaie de créer un simple recyclerView en Kotlin avec des données que je reçois via Volley (qui, je l'ai confirmé, renvoie les données correctes), mais je tombe toujours sur l'erreur suivante E/RecyclerView: No adapter attached; skipping layout alors qu'en fait j'ai spécifié un adaptateur avec la classe d'adaptateur personnalisée que j'ai créée :

class ImageAdapter(var c: Context, var list: ArrayList<Image>) : RecyclerView.Adapter<ImageAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder? {
    val layoutInflater = LayoutInflater.from(parent.context)
    return ViewHolder(layoutInflater.inflate(R.layout.image_cardview, parent, false))
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val imageUrl = list[position].url
    val submitter = list[position].submitter
    val color = list[position].color
    holder.submitterTV.text = submitter
    holder.card.setCardBackgroundColor(Color.parseColor(color))
}

override fun getItemCount() = list.size
class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView){
    val card = itemView.card
    val submitterTV = itemView.submitter
    val imageView = itemView.image
}

}

C'est ma classe MainActivty, où je fais l'appel réel pour le JSON et où j'essaie d'attacher mon adaptateur avec ma ArrayList que j'ai créée :

class MainActivity : AppCompatActivity() {
val images = ArrayList<Image>()
override fun onCreate(savedInstanceState: Bundle?) {

    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    imageList.layoutManager = LinearLayoutManager(applicationContext)
    request("https://api.unsplash.com/photos/curated/?client_id=API_KEY")
    imageList.adapter = ImageAdapter(applicationContext, images)

}

private fun request(url: String) {
    val queue = Volley.newRequestQueue(this)
    val stringRequest = JsonArrayRequest(url, Response.Listener<JSONArray> { response ->
        try {
            for (i in 0..(response.length() - 1)) {
                val image: Image = Image(response.getJSONObject(i).getJSONObject("urls").getString("full"), response.getJSONObject(i).getJSONObject("user").getString("username"), response.getJSONObject(i).getString("color"))
                images.add(image)
            }

            imageList.adapter.notifyDataSetChanged()

        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }, Response.ErrorListener { })
    queue.add(stringRequest)
}
}

J'ai créé une classe de données personnalisée Image qui stocke trois champs : l'imageUrl, l'expéditeur et la couleur, qui sont tous dérivés du JSON. Je pensais qu'appeler notifyDataSetChanged() sur mon adaptateur après que la requête ait été complétée permettrait à la recyclerView d'être mise à jour et d'afficher les articles, mais rien du tout ne s'affiche à l'écran. Quelqu'un a-t-il une idée de l'endroit où je me suis trompé ?

0voto

Nepster Points 893

J'ai créé un bel adaptateur qui a peut-être aidé à réduire le code

class ResultActivity : BaseActivity() {

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

        if (intent != null) {
            var results = intent.getParcelableArrayListExtra<Parcelable>("keyResults") as ArrayList<ResultBO>

            if (results.size > 0) {
                recycler_view.adapter = ResultAdapter(results, object : OnRecyclerItemClickListener {
                    override fun onItemClicked(view: View?, position: Int) {
                        /*var intent = Intent(this@SubjectListActivity,McqActivity::class.java)
                        intent.putExtra("keyTagBO",subjects.get(position))
                        startActivity(intent)*/
                    }
                });
            }
        }

    }
}

item_result.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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView
        android:id="@+id/titleTv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Dummy Value"
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Large" />

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

        <TextView
            android:id="@+id/option1Tv"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Dummy"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

        <TextView
            android:id="@+id/option2Tv"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Dummy Value"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    </LinearLayout>

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

        <TextView
            android:id="@+id/option3Tv"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Dummy"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

        <TextView
            android:id="@+id/option4Tv"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Dummy Value"
            android:textAlignment="center"
            android:textAppearance="@style/TextAppearance.AppCompat.Medium" />

    </LinearLayout>

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

    </LinearLayout>
</LinearLayout>

ResultADapter.class

class ResultAdapter(items: List<ResultBO>, onRecyclerItemClickListener: OnRecyclerItemClickListener) : BaseAdapter<ResultBO, ResultViewHolder>(items, onRecyclerItemClickListener) {

    override fun onCreateViewHolder(parent: ViewGroup, pos: Int): ResultViewHolder {
        return ResultViewHolder(parent, R.layout.item_result,onRecyclerItemClickListener)
    }
}

BaseViewHolder.class

abstract class BaseViewHolder<T : BaseModel>(parent: ViewGroup, @LayoutRes itemLayoutId: Int,
                                             var onRecyclerItemClickListener: OnRecyclerItemClickListener) :
        RecyclerView.ViewHolder(LayoutInflater.from(parent.context).inflate(itemLayoutId, parent,
                false)), View.OnClickListener {

    override fun onClick(v: View?) {
        onRecyclerItemClickListener.onItemClicked(v, adapterPosition)
    }

    abstract fun bindData(data: T)

    init {
        itemView.setOnClickListener(this)
    }
}

BaseAdapter

abstract class BaseAdapter<T : BaseModel, U : BaseViewHolder<T>>
(var items: List<T>, var onRecyclerItemClickListener: OnRecyclerItemClickListener)
    : RecyclerView.Adapter<U>() {

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

    override fun onBindViewHolder(holder: U, pos: Int) {
        holder.bindData(items.get(pos))
    }
}

ResultViewHolder.class

class ResultViewHolder(parent: ViewGroup, itemLayoutId: Int, onRecyclerItemClickListener: OnRecyclerItemClickListener) : BaseViewHolder<ResultBO>(parent, itemLayoutId, onRecyclerItemClickListener) {

    override fun bindData(data: ResultBO) {
        itemView.titleTv.setText(data.questionBO.title)

        itemView.option1Tv.setText(data.questionBO.options.get(0))
        itemView.option2Tv.setText(data.questionBO.options.get(1))
        itemView.option3Tv.setText(data.questionBO.options.get(2))
        itemView.option4Tv.setText(data.questionBO.options.get(3))

        when(data.orignalAnswer()) {
            OptionType.A -> itemView.option1Tv.setBackgroundColor(Color.GREEN)
            OptionType.B -> itemView.option2Tv.setBackgroundColor(Color.GREEN)
            OptionType.C -> itemView.option3Tv.setBackgroundColor(Color.GREEN)
            OptionType.D -> itemView.option4Tv.setBackgroundColor(Color.GREEN)
        }

        if(!data.isCorrectlyAnswered()){
            when(data.selectedOption) {
                OptionType.A -> itemView.option1Tv.setBackgroundColor(Color.RED)
                OptionType.B -> itemView.option2Tv.setBackgroundColor(Color.RED)
                OptionType.C -> itemView.option3Tv.setBackgroundColor(Color.RED)
                OptionType.D -> itemView.option4Tv.setBackgroundColor(Color.RED)
            }
        }

    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X