【问题标题】:Implementation of several views in one recyclerViews在一个recyclerViews中实现多个视图
【发布时间】:2020-06-13 17:03:25
【问题描述】:

如何在 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
                }
            }
        }

    }
}

我会补充一点,我是一个初学者,我还不能做很多事情

【问题讨论】:

  • 好的。我已经完成了

标签: android kotlin


【解决方案1】:

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

    ...
}

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

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
        }

    }
}

Here are the official tutorials 了解如何创建具有不同类型视图的适配器。

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

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

sealed class + objects + 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
        }
}

【讨论】:

  • 我尝试使用您的提示,但我认为我没有足够的技能来理解它。而且代码还是不行
  • 尝试关注this detailed tutorial from Google,了解如何创建能够生成多个不同视图的适配器。可能需要至少 30 分钟才能完成。但它提出的想法与我的回答相同。
  • 我按照指示做了,也做了谷歌教程。教程应用程序非常广泛。使用之前课程中的代码。尽管课程中的代码可以正常工作,但我仍然不知道如何在我的情况下使用它。顺便说一句,感谢您的耐心和愿意提供帮助的意愿。
  • @MatiR,不客气!如果您可以将您的应用程序上传到 GitHub 或类似网站,我可以创建一些推送请求来帮助您,只是为了解释。
  • 好的。这是我的项目:github.com/matir85/LearningRecyclerView
猜你喜欢
  • 2018-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多