kotlin recyclerview 数据未显示 [英] kotlin recyclerview data not showing
问题描述
我们的问题是如何从两个 SQLite DB 表中显示父子数据?
Our question is how to show Parent and Child data from two SQLite DB tables?
我们有两个表,它们被添加到两个 ArrayList childList
和 parentList
.
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 文件
ViewActivity
has this XML file
<?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.
我们尝试了各种更改,但无法显示 parent List
尽管使用 theGET
有趣的是显示 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
中以有组织的方式显示Parent和Child数据?
So our question is how to show Parent and Child data in a organized fashion in the View Activity
?
我们正在添加基于@Cruces 答案的新代码
此代码的一些问题无法理解
1.我们没有办法运行fun join来创建newList
2. 父子ViewHolder只能用包含类的接收者调用
3.内部类太多,需要外部嵌套注解吗?
4. 或者如果父子进程都实现了一个接口,一个 List<;项目 >)
我们不知道如何编写接口并将其连接到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 的修复
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
它将加载父数据没有子数据
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)
//}
}
}
从活动调用加入适配器是问题吗??这个活动有一个带有 RecyclerView rv_parent 的 XML 关联文件
Calling the Join Adapter from a Activity is the issue? ? This Activity has a XML associated file with a RecyclerView rv_parent
推荐答案
这里是一个答案和关于这个应用程序设计的一些观察
答案不会将父数据和子数据都放在同一个 Recycler 视图列表中
但答案可能有助于通过进一步探索解决问题!
我们所做的是创建父列表,当单击父部门时,将显示相应的子项.这可能是一个更实用的设计,而购物时您只需要在该部分查看生产项目.这意味着更少地滚动浏览单个家长和孩子的主列表.
Here is a answer and some observations about the design of this app
The answer does NOT place both the parent and child data on the same Recycler View List
But the answer may help to solve the issue With further exploration!
What we did was create the parent list and when the Parent Dept is clicked on the corresponding Child Items will be displayed. This may be a more functional design while shopping you only need to look at Produce items while in that section. This means less scrolling through a single master list of Parents and Children.
关于我们猜测的设计的一两句话,我们猜测一家杂货店可能有 20 个或更多部门(父级),因此您计划如何知道哪些项目(子数据)连接到适当的部门(父级)需要在以下情况下进行彻底的重新设计构建这两个列表.
A word or two about the design we are guessing a grocery store might have 20 or more Departments (Parents) so how you plan to know which Items (Child data) is connected to the appropriate Dept (Parent) needs drastic redesign when building these two lists.
如果您从 GitHub 下载了代码,您将更好地了解这种设计缺陷
If you downloaded the code from GitHub you will have a better grasp about this design deficiency
这是带有 XML 文件的所有代码
Here is all the code with the XML files
主活动导航到查看活动
fun onViewAll(view: View){
val intent = Intent(this,ViewActivity::class.java)
intent.putExtra("pickADAPTER",2)
startActivity(intent)
}
这是查看活动
Here is the View Activity
class ViewActivity : AppCompatActivity() {
lateinit var recyclerView: RecyclerView
private var RecyclerAdapter1: ViewAdapter? = null
private var RecyclerAdapter2: ViewChildAdapter? = null
private var linearLayoutManager: LinearLayoutManager? = null
private val db = DBHelper(this)
private var parentList:List<ModelParent> = ArrayList()
private var childList:List<ModelChild> = ArrayList()
var idD = 0
var whichADAPTER = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_view)
val bundle: Bundle = intent.extras
idD = bundle.getInt("BIGi", 0)
whichADAPTER = bundle.getInt("pickADAPTER",0)
initRecycler()
}// end onCreate
override fun onResume() {
super.onResume()
initDB()
}
private fun initDB() {
parentList = db.queryDEPT()
childList = db.queryCHILD(idD)
// 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"
}
if(whichADAPTER == 2) {
RecyclerAdapter1 = ViewAdapter(parents = parentList, context = applicationContext)
(recyclerView as RecyclerView).adapter = RecyclerAdapter1
}else{
RecyclerAdapter2 = ViewChildAdapter(children = childList)
(recyclerView as RecyclerView).adapter = RecyclerAdapter2
}
}
private fun initRecycler() {
val db = DBHelper(this)
childList = db.queryITEM()
parentList = db.queryDEPT()
recyclerView = rv_parent
recyclerView = this.findViewById(R.id.rv_parent)
RecyclerAdapter1 = ViewAdapter(parents = parentList, context = applicationContext)
linearLayoutManager = LinearLayoutManager(applicationContext)
(recyclerView as RecyclerView).layoutManager = linearLayoutManager!!
}
这里是查看活动的 XML 文件
Here the XML file for View Activity
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_parent"
android:layout_width="match_parent"
android:layout_height="match_parent" />
这是视图适配器
Here is the View Adapter
class ViewAdapter(private val parents: List<ModelParent>, internal var context: Context):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.editCLICK.setOnClickListener {
val i = Intent(context, ViewActivity::class.java)
i.putExtra("BIGi",parent.idD)
i.flags = Intent.FLAG_ACTIVITY_NEW_TASK
context.startActivity(i)
}
}
inner class ViewHolder(itemView : View) : RecyclerView.ViewHolder(itemView){
//val recyclerView : RecyclerView = itemView.rv_child
val textView: TextView = itemView.textView
var editCLICK: RelativeLayout = itemView.findViewById(R.id.editCLICK) as
RelativeLayout
和膨胀的 XML
And the inflated 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="#FF0000"
card_view:cardCornerRadius="5dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:id="@+id/editCLICK"
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="10dp"
android:background="@color/color_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="50dp"
android:layout_marginBottom="0dp"
android:orientation="horizontal"
android:paddingLeft="4dp"
android:paddingTop="6dp"
tools:layout_editor_absoluteX="74dp" />
</RelativeLayout>
这是DBHelper中的搜索例程
This is the search routine in DBHelper
fun queryCHILD(fkI: Int): List<ModelChild> {
val db = this.writableDatabase
val childList = ArrayList<ModelChild>()
val selectQuery = "SELECT * FROM $CHILD_TABLE WHERE $colCFK = ?"
val cursor = db.rawQuery(selectQuery, arrayOf(fkI.toString()))
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
val contact = ModelChild()
contact.idI = Integer.parseInt(cursor.getString(cursor.getColumnIndex(colidI)))
contact.item = cursor.getString(cursor.getColumnIndex(colItem))
contact.fkI = Integer.parseInt(cursor.getString(cursor.getColumnIndex(colCFK)))
childList.add(contact)
} while (cursor.moveToNext())
}
}
cursor.close()
return childList
}
需要注意的一件事是我们将 OnClickListener 附加到相对布局
One thing to make note of we attached the OnClickListener to a Relative Layout
holder.editCLICK.setOnClickListener
为什么我们不确定您是否可以从设置为侦听器的 RecyclerView 中获取 parent.idD
类型信息?
我们需要探索这一点,但在我们的测试中,我们尝试时代码失败了.
Why we are not sure you can obtain parent.idD
type information from a RecyclerView set as a listener?
We need to explore this but in our testing the code failed when we tried.
这篇关于kotlin recyclerview 数据未显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!