Kotlin Recyclerview数据未显示 [英] kotlin recyclerview data not showing

查看:186
本文介绍了Kotlin Recyclerview数据未显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的问题是如何显示两个SQLite数据库表中的父级和子级数据?

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

我们有两个表被添加到两个ArrayLists childListparentList.

We have two tables that are added to two ArrayLists childList and parentList.

这是每个模型类的

class ModelParent {
    var idD:Int = 0
    var dept:String = ""
    var fkD:Int = 0
    var children: List<ModelChild> = mutableListOf()
    //var children: ArrayList<ModelChild>? = null
    //var children: List<ModelChild>  by Delegates.notNull()
    constructor (children: List<ModelParent>) : this()
    companion object {
       var globalVar = 1
   }
}

class ModelChild {
    var idI:Int = 0
    var item:String = ""
    var fkI:Int = 0
}

每个表都有两个适配器,并将发布该代码
我们可以使用此代码遍历两个ArrayList,并以我们希望在ViewActivity中显示的格式显示数据.

We have two Adapters for each table and will post that code
We are able to iterate through the two ArrayList with this code and display the data in the format we would like to show in the ViewActivity.

fun theGET(){
    val db = DBHelper(this)
    childList = db.queryITEM()
    parentList = db.queryDEPT()
    var PL = parentList.size

    do {
        var DEPT: String = parentList[z].dept
        var PARENT_LIST_FK = parentList.get(z).fkD
            println("========== Dept " + DEPT + " fkD " + PARENT_LIST_FK)
        val FK = PARENT_LIST_FK
        childList = db.queryALL(FK)
        var CL = childList.size
        for (a in 0..CL - 1) {
            var CHILD_ITEM = childList[a].item
            var CHILD_LIST_FK = childList[a].fkI
            println("========== item " + CHILD_ITEM+" fkI "+CHILD_LIST_FK)
        }
        z++
    }
    while (z <= PL-1)
}

我们将发布View Activity

class ViewActivity : AppCompatActivity() {
    lateinit var recyclerView: RecyclerView

    private var parentList:List<ModelParent> = ArrayList()
    private var childList:List<ModelChild> = ArrayList()

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

        initRecycler()

    }// end onCreate

    private fun initRecycler() {
        val db = DBHelper(this)
        childList = db.queryITEM()
        parentList = db.queryDEPT()

        recyclerView = rv_parent

        recyclerView.apply{
            layoutManager = LinearLayoutManager(this@ViewActivity, LinearLayout.VERTICAL, false)
            adapter = ViewAdapter(parentList)
            adapter = ViewChildAdapter(children = childList)
        }
    }
}

ViewActivity拥有此XML文件

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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=".ViewActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>

两个适配器和对应的XML文件

The Two Adapters and coresponding XML files

class ViewAdapter(private val parents:List<ModelParent>):RecyclerView.Adapter<ViewAdapter.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.the_view,parent,false)
        return ViewHolder(view)
    }

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

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val parent = parents[position]
        holder.textView.text = parent.dept
        holder.recyclerView.apply {
            layoutManager = LinearLayoutManager(holder.recyclerView.context, LinearLayout.VERTICAL, false) as RecyclerView.LayoutManager?
            adapter = ViewChildAdapter(parent.children!!)
        }
    }

    inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
        val recyclerView : RecyclerView = itemView.rv_child
        val textView: TextView = itemView.textView
    }
}

class ViewChildAdapter(private val children:List<ModelChild>):RecyclerView.Adapter<ViewChildAdapter.ViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.child_recycler,parent,false)
        return ViewHolder(view)
    }
    override fun getItemCount(): Int {
        return children.size
    }
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val child = children[position]
        holder.textView.text = child.item
    }

    inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
        val textView : TextView = itemView.child_textView
    }
}

膨胀的XML文件

<android.support.v7.widget.CardView 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="2dp"
    card_view:cardBackgroundColor="#fff"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="4dp"
    card_view:cardUseCompatPadding="true">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <TextView
            android:id="@+id/textView"
            style="@style/Base.TextAppearance.AppCompat.Subhead"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignStart="@+id/rv_child"
            android:layout_alignParentTop="true"
            android:padding="20dp"
            android:background="@color/color_super_lightGray"
            android:text="Dept Header"
            android:textColor="@color/color_Purple"
            android:textSize="24sp"
            android:textStyle="bold" />

        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_child"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentTop="true"
            android:layout_alignParentBottom="true"
            android:layout_marginTop="70dp"
            android:layout_marginBottom="0dp"
            android:orientation="horizontal"
            android:paddingLeft="4dp"
            android:paddingTop="8dp"
            tools:layout_editor_absoluteX="74dp" />
    </RelativeLayout>
</android.support.v7.widget.CardView>

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="horizontal"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/child_textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginStart="32dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        android:background="@color/color_Transparent"
        android:padding="10dp"
        android:text="TextView"
        android:textColor="@color/color_Black"
        android:textSize="20sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0" />

仅加载ViewActivity时,将显示childList.

When the ViewActivity is loaded ONLY the childList is displayed.

我们尝试了各种更改,但尽管使用theGET却无法显示parent List,因此会显示parentList数据,因此我们知道它在列表中.

We have tried various changes and can not display the parent List though using theGET fun the parentList data is displayed so we know it is in the list.

我们可以运行有趣的theGET并创建似乎无用的新ArrayList.

We can run the fun theGET and crate a new ArrayList that seems futile.

我们担心的是,先显示parentList,然后在显示childList时将其删除.

Our concern is that the parentList is displayed and then removed when the childList is displayed.

我们不知道如何证明这一点.

We do not know how to prove this.

所以我们的问题是如何在View Activity中以有组织的方式显示父子数据?

So our question is how to show Parent and Child data in a organized fashion in the View Activity?

我们正在基于@Cruces答案添加新代码
此代码的一些问题是无法理解的
1.我们无法运行有趣的联接来创建newList
2.父级和子级ViewHolder只能与包含Class
的接收者一起调用 3.内部类太多,我们是否需要外部嵌套批注?
4. or if both parent and child implement an interface a List< IItem > )
我们不知道如何编写接口并将其连接到JoinAdapter

We are adding New CODE based on @Cruces answer
Some issues with this code are beyond out understanding
1. We have no way to run the fun join to create the newList
2. Parent and Child ViewHolder can be called only with receiver of containing Class
3. Too many inner Class's and do we need an Outer Nested annotation?
4. or if both parent and child implement an interface a List< IItem > )
We do not know how to write an interface and connect it to the JoinAdapter

虽然答案提出了一个新问题,但我们认为在这种情况下最好问=上下文幽默 这是JoinAdapter的FIX

While the answer poses new question we feel it better to ask with in this context = Context HUMOR Here is the FIX for the JoinAdapter

class JoinAdapter(internal var context: Context, val parents: List<ModelParent>) : RecyclerView.Adapter<JoinAdapter.MyViewHolder>() {
val items = mutableListOf<Any>()

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.the_view, parent, false)
        return ParentViewHolder(view!!)
    } else {
        view = LayoutInflater.from(parent.context).inflate(R.layout.child_recycler, 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) {
    override fun bindData(position: Int, item: Any) {
        val parent = item as? ModelParent ?: return
        parent.dept
        parent.fkD
        parent.children
        //bind the data here
    }

    init {
        val textView: TextView = view.textView
        var editCLICK: RelativeLayout = view.findViewById(R.id.editCLICK) as RelativeLayout
        //do the view setup here
    }

}

inner class ChildViewHolder(view: View) : MyViewHolder(view) {
    init {
        val textView : TextView = itemView.child_textView
        //do the view setup here
    }

    override fun bindData(position: Int, item: Any) {
        val child = item as? ModelChild ?: return
        child.item
        child.idI
        //bind the data here
    }
}

我将把View Activity调用发布到Join Adapter
代码不会失败,它什么也不显示?

I am going to post the View Activity call to Join Adapter
Code does not FAIL it just shows nothing?

        RecyclerAdapter1 = JoinAdapter(parents = ArrayList(),context = applicationContext)
    (recyclerView as RecyclerView).adapter = RecyclerAdapter1

这是ViewJoinActivity,它将加载父数据NO子数据

Here is the ViewJoinActivity it will load the Parent Data NO Child Data

class ViewJoinActivity : AppCompatActivity() {

lateinit var recyclerView: RecyclerView
private var RecyclerAdapter: JoinAdapter? = null
private var linearLayoutManager: LinearLayoutManager? = null
private val db = DBHelper(this)
private var parentList:List<ModelParent> = ArrayList()
private var childList:List<ModelChild> = ArrayList()

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

}// end onCreate

override fun onResume() {
    super.onResume()
    initDB()
}

private fun initDB() {
    parentList = db.queryDEPT()
    //childList = db.queryCHILD(1)
    childList = db.queryITEM()
    // queryCHILD only selects records with a fkI equal to idD
    // SEE THE ModelChild and ModelParent
    if(parentList.isEmpty()){
        title = "No Records in DB"
    }else{
        title = "Parent List"
    }

        RecyclerAdapter = JoinAdapter(parents = parentList, context = applicationContext)
        (recyclerView as RecyclerView).adapter = RecyclerAdapter
    }

private fun initRecycler() {
    val db = DBHelper(this)
    childList = db.queryITEM()
    parentList = db.queryDEPT()

    //recyclerView = rv_parent

    /*var PL = parentList.size
    newList.clear()
    do {
        var DEPT: String = parentList[z].dept
        var ND:String = DEPT
        var PARENT_LIST_FK = parentList.get(z).fkD
        var PL_ST = ND+" "+PARENT_LIST_FK
        newList.add(PL_ST)

        println("========== Dept " + DEPT + " fkD " + PARENT_LIST_FK)
        val FK = PARENT_LIST_FK

        childList = db.queryCHILD(FK)
        var CL = childList.size

        for (a in 0..CL - 1) {
            var CHILD_ITEM = childList[a].item
            var NI:String = childList[a].item
            var CHILD_LIST_FK = childList[a].fkI
            var IL_ST = NI+" "+CHILD_LIST_FK
            newList.add(IL_ST)
            println("========== item " + CHILD_ITEM+" fkI "+CHILD_LIST_FK)
        }
        z++

        g++
    }
    while (z <= PL-1)


    var ui = newList.size
    g=0
    for(g in 0..ui-1){
        var N2 = newList[g]

        if(N2.toString().contains("1")){
            println("********************** We Found "+N2)

        }
        println("############### BOTH = "+N2)

    }*/

    recyclerView = this.findViewById(R.id.rv_parent)
    RecyclerAdapter = JoinAdapter(parents = parentList, context = applicationContext)
    linearLayoutManager = LinearLayoutManager(applicationContext)
    (recyclerView as RecyclerView).layoutManager = linearLayoutManager!!

    //recyclerView.apply {
        //layoutManager = LinearLayoutManager(this@ViewJoinActivity, LinearLayout.VERTICAL, false)
        //adapter = JoinAdapter(children = childList)
    //}

}

}

从活动中调用加入适配器是问题吗? ? 该活动具有一个XML关联文件,该文件带有RecyclerView rv_parent

Calling the Join Adapter from a Activity is the issue? ? This Activity has a XML associated file with a RecyclerView rv_parent

推荐答案

我这样做的方法是使列表变平edit: like this in the constructor

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

val items : MutableList<Any> = mutableListOf<Any>()    

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

我将创建一个列表<任何>(或者如果父级和子级都实现了一个List 的接口),它将包含您希望看到的所有数据,因此例如,它看起来可能像这样:

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<Any> = 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_child:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="2dp"
    card_view:cardBackgroundColor="#fff"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="4dp"
    card_view:cardUseCompatPadding="true">

    <TextView
        android:id="@+id/child_item"
        style="@style/Base.TextAppearance.AppCompat.Display3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:padding="20dp"
        android:textSize="24sp"
        android:textStyle="bold"
        tools:text="Dept Header" />

</android.support.v7.widget.CardView>

list_item_parent:

list_item_parent:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="2dp"
    card_view:cardBackgroundColor="#fff"
    card_view:cardCornerRadius="5dp"
    card_view:cardElevation="4dp"
    card_view:cardUseCompatPadding="true">

    <TextView
        android:id="@+id/parent_department"
        style="@style/Base.TextAppearance.AppCompat.Headline"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:padding="20dp"
        tools:text="Dept Header"
        android:textSize="24sp"
        android:textStyle="bold" />

</android.support.v7.widget.CardView>

,适配器看起来像这样:

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<ModelChild>)
data class ModelChild(val id: Int)


class JoinAdapter(internal var context: Context, val parents: List<ModelParent>) : RecyclerView.Adapter<JoinAdapter.MyViewHolder>() {
    val items = mutableListOf<Any>()

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

}

在单个recyclerview上使用时,它将在列表中显示其父项下的所有子项

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

这篇关于Kotlin Recyclerview数据未显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆