webentwicklung-frage-antwort-db.com.de

Der Versuch, eine einfache RecyclerView in Kotlin zu erstellen, der Adapter wird jedoch nicht ordnungsgemäß angewendet

Ich versuche, in Kotlin eine einfache RecyclerView mit Daten zu erstellen, die ich über Volley erhalten habe (was die korrekten Daten bestätigt). Ich renne ständig zum Fehler E/RecyclerView: No adapter attached; skipping layout, wenn ich tatsächlich einen Adapter mit der benutzerdefinierten Adapterklasse angegeben habe Ich erschuf:

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
}

}

Dies ist meine MainActivty-Klasse, in der ich den eigentlichen Aufruf für die JSON mache und versuche, meinen Adapter mit meiner von mir erstellten ArrayList anzuhängen:

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)
}
}

Ich habe eine benutzerdefinierte Datenklasse Image erstellt, die drei Felder speichert: imageUrl, übergebender Benutzer und Farbe, die alle von der JSON abgeleitet sind. Ich dachte, der Aufruf von notifyDataSetChanged() auf meinem Adapter nach Abschluss der Anforderung würde es dem RecyclerView ermöglichen, aktualisiert zu werden und die Elemente anzuzeigen, aber auf dem Bildschirm wird überhaupt nichts angezeigt. Hat jemand eine Ahnung, wo ich versaut habe?

6
rakeshdas

Sie können den Quellcode von hier herunterladen ( Recyclerview In Kotlin Android )

MainActivity.kt:

package com.deepshikha.recyclerviewkotlin
import Android.app.Activity
import Android.os.Bundle
import Android.support.v7.widget.LinearLayoutManager
import Android.view.Window
import Android.view.WindowManager
import Android.widget.LinearLayout
import kotlinx.Android.synthetic.main.activity_main.*
import net.simplifiedcoding.recyclerviewexample.CustomAdapter

class MainActivity : Activity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        requestWindowFeature(Window.FEATURE_NO_TITLE)
        window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)

        setContentView(R.layout.activity_main)

        val users = ArrayList<Model_Details>()
        users.add(Model_Details("Kaju katli", "Kaju katli, also known as kaju Katari or kaju barfi, is an Indian dessert similar to a barfi.",R.drawable.kaju))
        users.add(Model_Details("Doughnut", "The doughnut is popular in many countries and prepared in various forms as a sweet snack that can be homemade or purchased in bakeries, supermarkets, food stalls, and franchised specialty outlets",R.drawable.donuts))
        users.add(Model_Details("Panna cotta", "Panna cotta is an Italian dessert of sweetened cream thickened with gelatin and molded. The cream may be aromatized with rum, coffee, Vanilla, or other flavorings.",R.drawable.panna_cotta))
        users.add(Model_Details("Rose Cookies", "Rose cooky is a famous South Indian snack made during festivals",R.drawable.rosecookies))
        users.add(Model_Details("Belgian waffle", "In North America, Belgian waffles are a variety of waffle with a lighter batter, larger squares, and deeper pockets than ordinary American waffles",R.drawable.belgianwaffle))

        val obj_adapter = CustomAdapter(users)

        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
        recyclerView.adapter = obj_adapter
    }


}

CustomAdapter.kt:

package net.simplifiedcoding.recyclerviewexample

import Android.support.v7.widget.RecyclerView
import Android.view.LayoutInflater
import Android.view.View
import Android.view.ViewGroup
import Android.widget.TextView
import com.deepshikha.recyclerviewkotlin.Model_Details
import com.deepshikha.recyclerviewkotlin.R
import kotlinx.Android.synthetic.main.adapter_details.view.*

class CustomAdapter(val userList: ArrayList<Model_Details>) : RecyclerView.Adapter<CustomAdapter.ViewHolder>() {

    //this method is returning the view for each item in the list
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomAdapter.ViewHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.adapter_details, parent, false)
        return ViewHolder(v)
    }

    //this method is binding the data on the list
    override fun onBindViewHolder(holder: CustomAdapter.ViewHolder, position: Int) {
        holder.bindItems(userList[position])
    }

    //this method is giving the size of the list
    override fun getItemCount(): Int {
        return userList.size
    }

    //the class is hodling the list view
    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        fun bindItems(user: Model_Details) {
            itemView.tv_name.text=user.name
            itemView.tv_des.text=user.des
            itemView.iv_name.setImageResource(user.image)

        }
    }

}

Vielen Dank!

14
Deepshikha Puri

Schauen Sie sich folgendes Beispiel an, ich denke, Sie können damit eine Idee bekommen. 

Das Beispiel finden Sie hier: https://github.com/Siddharha/RecyclerviewTest_Kotlin

Hauptaktivität

class MainActivity : AppCompatActivity() {
private var myAdapter: MyAdapter? = null
private var arrayList: ArrayList<MyItem>? = null
private var layoutManager: RecyclerView.LayoutManager? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    initialize()
    setupList()
    loaddata()
}

private fun loaddata() {

    for (i in 0..9) {
        val myItem = MyItem()
        myItem.name = "Sid_" + i
        myItem.number = "098899876" + i
        arrayList!!.add(myItem)
    }

    myAdapter!!.notifyDataSetChanged()

}

private fun setupList() {
    rlItems!!.layoutManager = layoutManager
    rlItems!!.adapter = myAdapter
}

private fun initialize() {
    arrayList = ArrayList<MyItem>()
    layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)
    myAdapter = MyAdapter(arrayList!!, this, R.layout.item_cell)

  }
}

Adapterklasse

internal class MyAdapter(private val arrayList: ArrayList<MyItem>,
                     private val context: Context,
                     private val layout: Int) : RecyclerView.Adapter<MyAdapter.ViewHolder>() {


override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyAdapter.ViewHolder {
    val v = LayoutInflater.from(parent.context).inflate(layout, parent, false)
    return ViewHolder(v)
}

override fun onBindViewHolder(holder: MyAdapter.ViewHolder, position: Int) {
    holder.bindItems(arrayList[position])
}

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

internal inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

    fun bindItems(items: MyItem) {
        itemView.tvName.text = items.name
        itemView.tvNumber.text = items.number
    }
  }
}

Artikelklasse

internal class MyItem {
var name: String? = null
var number: String? = null
}
4
Sid

verwenden Sie die unten aufgeführten Delegate-Adapter als Referenzlink. 

Ref Link: https://Android.jlelse.eu/keddit-part-4-recyclerview-delegate-adapter-data-classes-with-kotlin-9248f44327f7

1
Sanjay Bhalani

On .MainActivity.kt

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

    //rcv is id of Recyclerview
    rcv.layoutManager = LinearLayoutManager(this)
    rcv.adapter = MyAdpater()
}

Erstellen Sie eine neue .kt-Datei zum Erstellen eines Adapters

class MyAdpater : RecyclerView.Adapter<ViewHolder>() {
val arr = listOf("A", "B", "C", "D", "E") //static array
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    holder.textView.setText(arr.get(position)) //set text to textview by position
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder(TextView(parent.context))
 }

override fun getItemCount(): Int {
    return arr.count() //return array count
}}

class ViewHolder(val textView: TextView): RecyclerView.ViewHolder(textView){ //ViewHolder with textview}
0
iOS Lifee

Ich habe einen Nice-Adapter erstellt. Vielleicht hilft es, den Code zu reduzieren.

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([email protected],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)
            }
        }

    }
}
0
Xar E Ahmer

Ich habe meinen RecyclerView-Adapter, der wie folgt lautet: 

internal class OptionsAdapter : RecyclerView.Adapter<OptionsAdapter.ViewHolder>() {

private val mOptionList = ArrayList<Option>()
private var mOnItemClickListener: OnItemClickListener<Option>? = null

var data: List<Option>
    get() = mOptionList
    set(list) {
        mOptionList.clear()
        mOptionList.addAll(list)
        notifyDataSetChanged()
    }

fun setOnItemClickListener(listener: OnItemClickListener<Option>) {
    mOnItemClickListener = listener
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    return ViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.layout_text, parent, false))
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
    val option = getItem(position)
    holder.textViewOption.setText(option.text)
    holder.textViewDescription.setText(option.subText)
}



private fun getItem(index: Int): Option {
    return mOptionList[index]
}

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


internal inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
    var textViewOption: TextView
    var textViewDescription: TextView
    var imageViewOptionIcon: ImageView

    init {
        textViewOption = itemView.findViewById<TextView>(R.id.textview_option)
        imageViewOptionIcon = itemView.findViewById<ImageView>(R.id.imageview_option_icon)
        textViewDescription = itemView.findViewById<TextView>(R.id.textview_description)
        itemView.setOnClickListener {
            if (mOnItemClickListener != null) {
                mOnItemClickListener!!.onItemClick(getItem(adapterPosition))
            }
        }
    }
  }
}
0