kotlin recyclerview data not showing

后端 未结 3 1413
臣服心动
臣服心动 2020-12-04 04:22

Our question is how to show Parent and Child data from two SQLite DB tables?

We have two tables that are added to two ArrayLists childList and par

3条回答
  •  不思量自难忘°
    2020-12-04 04:42

    The way I would do it is flatten the list edit: like this in the constructor

    val items : MutableList = mutableListOf()    
    
    init() {
       parents //parents should be passed as a constructor argument
             .asSequence() //this is only needed if you want to also order them
             .sortedBy { it.idD } //again only if you want to sort them
             .forEach { 
                  items.add(it)
                  items.addAll(it.children)
              }
    }
    

    I would create a List < Any > (or if both parent and child implement an interface a List< IItem > ) that would contain all the data as you wish to see it, so for example it could look like this:

    val items : List = listOf(parent1, child11,child12,child13,parent2,child12,child13,child14.....etc)
    

    then I would implement a single adapter with multiple view types like this:

    override fun getItemCount(): Int {
        return items.size
    }
    
    fun getItem(position: Int) : Any { //or the interface 
        return items[position]
    }
    
    override getItemViewType (position: Int) : Int {
        if (getItem(position) is ModelParent)
            return 0
        return 1
    }
    
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        var view : View? = null
        if (viewType == 0) {
            view = LayoutInflater.from(parent.context).inflate(R.layout.parent_layout,parent,false)
            return ParentViewHolder(view);
        } else {
           view = LayoutInflater.from(parent.context).inflate(R.layout.child_layout,parent,false)
            return ChildViewHolder(view);
        }
    }
    

    and then I would use two view holders to represent how the data is shown for the specific item

     inner class ParentViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){ ...}
     inner class ChildViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){ ...}
    

    after that I could perform different bindings by getting the type of the view ,something like this:

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        if (getItemType(position) == 0) {
            (holder as ParentViewHolder).bindData(....)
        } else {
            (holder as ChildViewHolder).bindData(....)
        }
    }
    

    edit: Here is the complete adapter I built, it is based on two layout files:

    list_item_child:

    
    
        
    
    
    

    list_item_parent:

    
    
        
    
    
    

    and the adapter would look something like this:

    import android.content.Context
    import android.support.v7.widget.RecyclerView
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import android.widget.TextView
    
    data class ModelParent(val id: Int, val children: List)
    data class ModelChild(val id: Int)
    
    
    class JoinAdapter(internal var context: Context, val parents: List) : RecyclerView.Adapter() {
        val items = mutableListOf()
    
        init {
            parents //parents should be passed as a constructor argument
                    .forEach {
                        items.add(it)
                        items.addAll(it.children)
                    }
        }
    
        override fun getItemCount(): Int = items.size;
    
    
        fun getItem(position: Int): Any = items[position]
    
        override fun getItemViewType(position: Int): Int = if (getItem(position) is ModelParent) 0 else 1
    
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
            var view: View? = null
            if (viewType == 0) {
                view = LayoutInflater.from(parent.context).inflate(R.layout.rv_list_item_parent, parent, false)
                return ParentViewHolder(view!!)
            } else {
                view = LayoutInflater.from(parent.context).inflate(R.layout.rv_list_item_child, parent, false)
                return ChildViewHolder(view!!)
            }
        }
    
        override fun onBindViewHolder(holder: MyViewHolder, position: Int) = holder.bindData(position, getItem(position))
    
        inner abstract class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
            abstract fun bindData(position: Int, item: Any)
    
        }
    
        inner class ParentViewHolder(view: View) : MyViewHolder(view) {
            var parentDept: TextView = view.findViewById(R.id.parent_department) as TextView
    
            override fun bindData(position: Int, item: Any) {
                val parent = item as? ModelParent ?: return
                parentDept.text = parent.dept
            }
        }
    
        inner class ChildViewHolder(view: View) : MyViewHolder(view) {
            var childItem: TextView = view.findViewById(R.id.child_item) as TextView
    
            override fun bindData(position: Int, item: Any) {
                val child = item as? ModelChild ?: return
                childItem.text = child.item
            }
        }
    
    }
    

    this when used on a single recyclerview will display all children under their parent in a list

提交回复
热议问题