Android 在一个recyclerViews中实现多个视图

Android 在一个recyclerViews中实现多个视图,android,kotlin,Android,Kotlin,如何在Kotlin的一个recyclerViews中实现不同的视图 我想创建一个包含法律代码的应用程序。我的问题是,个别法律条款分为几章。如果我能创建一个程序来为我显示所有的食谱,我真的不知道如何把它放在recyclerView中,在布局和特定法律条款之间,布局和章节的编号和标题信息 下面的代码仍然显示了相同的视图 package pl.nynacode.naukapraw import android.view.LayoutInflater import android.view.View i

如何在Kotlin的一个recyclerViews中实现不同的视图

我想创建一个包含法律代码的应用程序。我的问题是,个别法律条款分为几章。如果我能创建一个程序来为我显示所有的食谱,我真的不知道如何把它放在recyclerView中,在布局和特定法律条款之间,布局和章节的编号和标题信息

下面的代码仍然显示了相同的视图

package pl.nynacode.naukapraw
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.cart_view_legal_name.view.*
import kotlinx.android.synthetic.main.chapter_layout.view.*

class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>(){
    class MyViewHolder(val view: View, val view2: View):RecyclerView.ViewHolder(view) {

    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val layoutInflater= LayoutInflater.from(parent.context);
        val legalName = layoutInflater.inflate(R.layout.cart_view_legal_name, parent ,false);
        val chapterName = layoutInflater.inflate(R.layout.chapter_layout, parent,false);
        return MyViewHolder(legalName, chapterName);
    }

    override fun getItemCount(): Int {
        return KodeksKarny.nrArticle.size;
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        when(position){
            0->{
                val chapter = holder.view2.tvChapterName;
                chapter.setText(KodeksKarny.nrArticle[position])
            }
            else->{
                val nrArticle = holder.view.nrArt;
                val textArticle=holder.view.txtArt;

                nrArticle.setText(KodeksKarny.nrArticle[position]);
                textArticle.setText(KodeksKarny.txtArticle[position]);

                // obsługa klikniecia na przycisk
                nrArticle.setOnClickListener{
                    if (textArticle.visibility == View.GONE){
                        textArticle.visibility = View.VISIBLE
                    }else textArticle.visibility = View.GONE
                }
            }
        }

    }
}
包pl.nynacode.naukapraw
导入android.view.LayoutInflater
导入android.view.view
导入android.view.ViewGroup
导入androidx.recyclerview.widget.recyclerview
导入kotlinx.android.synthetic.main.cart\u view\u legal\u name.view*
导入kotlinx.android.synthetic.main.chapter_layout.view*
类MyAdapter:RecyclerView.Adapter(){
类MyViewHolder(val视图:视图,val视图2:视图):RecyclerView.ViewHolder(视图){
}
重写CreateViewHolder(父级:ViewGroup,viewType:Int):MyViewHolder{
val layoutInflater=layoutInflater.from(parent.context);
val legalName=layoutInflater.flate(R.layout.cart\u view\u legal\u name,parent,false);
val chapterName=布局平坦。充气(R.layout.chapter_布局,父级,false);
返回MyViewHolder(法律名称、章节名称);
}
重写getItemCount():Int{
返回KodeksKarny.nrArticle.size;
}
覆盖onBindViewHolder(holder:MyViewHolder,位置:Int){
何时(职位){
0->{
val chapter=holder.view2.tvChapterName;
第.setText章(KodeksKarny.nArticle[位置])
}
其他->{
val nRact=holder.view.nrArt;
val textArticle=holder.view.txtArt;
narticle.setText(KodeksKarny.narticle[位置]);
textArticle.setText(KodeksKarny.txtArticle[position]);
//奥布斯卡·克里克尼西亚·纳普济西斯克
nrArticle.setOnClickListener{
if(textArticle.visibility==View.GONE){
textArticle.visibility=View.VISIBLE
}else textArticle.visibility=View.GONE
}
}
}
}
}

我要补充的是,我是一个初学者,我还不能做很多事情。Adapter有一个名为
fun getItemViewType(position:Int):Int
的方法,它返回给定位置的视图类型

基于该函数,您可以创建不同的视图保持架,或将不同的布局传递给相同的视图保持架类型(但避免最后一个)

您只需覆盖适配器中的一个函数,并确定该位置的项目类型:

override fun getItemViewType(position: Int): Int {
    val item = getItem(position)
    // the code below is just an example. 
    val type = when (item) {
        is Header -> HEADER_TYPE
        is NotHeader -> NOT_HEADER_TYPE
    }
    return type
}
在哪里可以定义这些类型?例如,在伴生对象中:

class YourAdapter: ... {
    companion object {
        private const val HEADER_TYPE = 0
        private const val NOT_HEADER_TYPE = 1
    }

    ...
}
稍后在
onCreateViewHolder
onBindViewHolder
中,您可以创建不同的视图持有者,并将您拥有的数据绑定到这些视图持有者

class YourAdapter: ... {
    companion object {
        private const val HEADER_TYPE = 0
        private const val NOT_HEADER_TYPE = 1
    }

    ...
    override fun getItemViewType(position: Int): Int {
        val item = getItem(position)
        // the code below is just an example. 
        val type = when (item) {
            is Header -> HEADER_TYPE
            is NotHeader -> NOT_HEADER_TYPE
        }
        return type
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        if (viewType == HEADER_TYPE) {
            // Here you create HeaderViewHolder
        } else {
            val layoutInflater= LayoutInflater.from(parent.context);
            val legalName = layoutInflater.inflate(R.layout.cart_view_legal_name, parent ,false);
            val chapterName = layoutInflater.inflate(R.layout.chapter_layout, parent,false);
            return MyViewHolder(legalName, chapterName);
        }
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        val itemViewType = getItemViewType(position)
        if (itemViewType == HEADER_TYPE) {
            // cast MyViewHolder to HeaderViewHolder, for example
            val header = viewHolder as HeaderViewHolder
            header.headerTitle.text = ...
        } else {
            val nrArticle = holder.view.nrArt;
            ... other type
        }

    }
}
介绍如何使用不同类型的视图创建适配器

我个人更喜欢实现
抽象类BaseViewHolder:RecyclerView.ViewHolder
,它将用作适配器实现的泛型类型参数。这个
BaseViewHolder
应该有一个抽象方法,比如
abstract-fun-bind(数据:YourDataType)
。该功能将由视图持有者实现,视图持有者将扩展
BaseViewHolder

另外,由于Kotlin为我们提供了密封类,我更喜欢创建一个密封类和从中扩展的对象来保存视图持有者类型,因此当您实现
onCreateViewHolder
方法时,它可以避免
else
情况。但这正是我喜欢的,并没有任何要求

密封类
+
对象
s+
onCreateViewHolder
的示例:

sealed class Types(val rawType: Int) {
    object Header: Types(0)
    object NotHeader: Types(1)

    companion object {
       fun from(rawType: Int) = 
           when (rawType) {
               Header.rawType -> Header
               NotHeader.rawType -> NotHeader
               else -> throw RuntimeException("No such type")
           }
    }
}

class YourAdapter ... {

    override fun getItemViewType(position: Int): Int {
        val item = getItem(position)
        // the code below is just an example. 
        val type = when (item) {
            is Header -> Types.Header.rawType
            is NotHeader -> Types.NotHeader.rawType
        }
        return type
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder =
        when (Types.from(viewType)) {
            is Types.Header -> // return HeaderViewHolder
            is Types.NotHeader -> // return NotHeaderViewHolder
        }
}

我试着用你的建议,但我认为我没有足够的技能去理解它。而且代码仍然不起作用。请尝试了解如何创建能够生成多个不同视图的适配器。可能至少需要30分钟才能完成。但它提出了和我在回答中相同的想法。我按照指示做了,并且做了谷歌教程。教程的应用相当广泛。使用上一课中的代码。虽然课程中的代码正常工作,但我仍然不知道如何在我的案例中使用它。顺便说一句,谢谢你的耐心和帮助。@MatiR,不客气!如果你可以将你的应用程序上传到GitHub或类似的网站,我可以创建一些推送请求来帮助你,只是为了解释一下。好的。这是我的项目:好的。我已经做完了