【问题标题】:Kotlin RecyclerView Add Loading footerKotlin RecyclerView 添加加载页脚
【发布时间】:2019-12-10 15:14:40
【问题描述】:

我使用此视频为我的 RecyclerView 实现了一个标头:https://www.youtube.com/watch?v=ksIpDnLiCMs

但是我不知道如何将加载页脚与 ProgressBar 集成,我尝试自己实现它但它不起作用,当我向下时它应该加载更多但无论我的滚动在哪里它都会继续加载位置,并且进度条不会出现。 这是我的代码:

MainActivity.kt:

class MainActivity : AppCompatActivity() {

    val numberList: MutableList<String> = ArrayList()

    var page = 1
    var isLoading = false
    var limit = 10

    lateinit var adapter: RV_Adapter
    lateinit var layoutManager: LinearLayoutManager

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


        layoutManager = LinearLayoutManager(this)
        recyclerView.layoutManager = layoutManager

        getPage()

        recyclerView.addOnScrollListener(object: RecyclerView.OnScrollListener() {
            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {

                val visibleItemCount = layoutManager.childCount
                val pastVisibleItem = layoutManager.findFirstCompletelyVisibleItemPosition()
                val total = adapter.itemCount

                if(!isLoading) {
                    if((visibleItemCount + pastVisibleItem) >= total) {
                        page++
                        getPage()
                    }
                }

                super.onScrolled(recyclerView, dx, dy)
            }
        })
    }

    fun getPage() {
        isLoading = true
        //progressBar.visibility = View.VISIBLE
        val start : Int = (page-1)*limit
        val end : Int = page * limit

        for(i in start..end){
            numberList.add("PodView " + i.toString())
        }
        Handler().postDelayed({
            if(::adapter.isInitialized) {
                adapter.notifyDataSetChanged()
            } else {
                adapter = RV_Adapter(this, numberList)
                recyclerView.adapter = adapter
            }
            isLoading = false
            //progressBar.visibility = View.GONE
        }, 0)

    }
}

RV_Adapter.kt

class RV_Adapter(private val context: Context, private val numberList: MutableList<String>) : RecyclerView.Adapter<BaseViewHolder<*>>() {

    companion object {
        private const val TYPE_HEADER = 0
        private const val TYPE_ITEMS = 1
        private const val TYPE_FOOTER = 2
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): BaseViewHolder<*> {

        return when(viewType) {
            TYPE_HEADER -> {
                val view = LayoutInflater.from(context).inflate(R.layout.rv_header, parent, false)
                HeaderViewHolder(view)
            }

            TYPE_ITEMS -> {
                val view = LayoutInflater.from(context).inflate(R.layout.listview_item, parent, false)
                ItemViewHolder(view)
            }

            TYPE_FOOTER -> {
                val view = LayoutInflater.from(context).inflate(R.layout.rv_footer, parent, false)
                FooterViewHolder(view)
            }

            else -> throw IllegalArgumentException("Invalid View Type")
        }

    }

    override fun getItemCount(): Int {
        return numberList.size + 1
    }

    override fun onBindViewHolder(holder: BaseViewHolder<*>, position: Int) {
        if(holder is ItemViewHolder){
            holder.numberBarText.text = numberList[position]
        }
        if(holder is HeaderViewHolder){
            holder.cardView.radius = 50f
        }


    }

    override fun getItemViewType(position: Int): Int {
        if(position == 0) {
            return TYPE_HEADER
        }

        return TYPE_ITEMS
    }

    inner class HeaderViewHolder(itemView: View): BaseViewHolder<View>(itemView) {
        val cardView : CardView = itemView.findViewById(R.id.profileImageCardView)

        override fun bind(item: View) {}

    }

    inner class ItemViewHolder(itemView: View): BaseViewHolder<View>(itemView) {
        val numberBarText = itemView.findViewById<TextView>(R.id.numberBarText)

        override fun bind(item: View) {}

    }
    inner class FooterViewHolder(itemView: View): BaseViewHolder<View>(itemView) {

        override fun bind(item: View) {}

    }
}

更新:

将我的 RecyclerView 与 BottomNavigationView 组合后,页脚和页眉出现故障。需要一个更可靠的解决方案,而不是向数组列表添加字符串,例如:numberList.add("VIEW_TYPE_FOOTER")

【问题讨论】:

    标签: android kotlin android-recyclerview


    【解决方案1】:

    为了在适配器中创建页脚项,您应该在代码中实现一些东西。

    首先你应该为你的页脚创建一个新的itemViewType。 您要做的第二件事是创建一种方法,告诉您的Adapter 这个视图实际上是一个页脚。由于您将ListString 一起使用,您应该在List 的末尾添加类似这样的内容:

    numberList.add("VIEW_TYPE_FOOTER")
    

    然后:

    override fun getItemViewType(position: Int): Int {
          val item = numberList[position]
          if(position == 0) {
              return TYPE_HEADER
          } else if(item == "VIEW_TYPE_FOOTER") {
              return TYPE_FOOTER
          }
          return TYPE_ITEMS
    }
    

    您应该检查 lastVisibleItem,而不是 firstVisible ,然后获取 nextPage。 请记住,在获取下一页后,您必须从 List 中删除最新的项目,这将是您的页脚视图,将下一页添加到 List,然后决定是否需要添加新页脚.

    希望这可以帮助您了解如何使其在您的情况下发挥作用。

    【讨论】:

    • 这个技巧对我有用,但是在我将 RecyclerView 与底部导航结合后,一切都变得非常糟糕。所以不幸的是,这种技术对我来说效率不高。
    • 您应该添加更多详细信息是什么问题以及您在做什么,以便我们提供帮助。我的回答是一个基本的想法,而不是真正的实现。
    【解决方案2】:

    考虑在适配器内部维护 isLoading 变量,并通过在适配器中添加以下方法从 MainActivity(取消)设置它:

    var isLoading:Boolean
    fun setIsLoading(value:Boolean) {
        isLoading = value
    }
    

    然后你可以像这样改变方法:

    override fun getItemCount(): Int {
        return numberList.size + 1
    }
    

    override fun getItemCount(): Int {
        return if(!isLoading) isnumberList.size + 1 else isnumberList.size + 2 
    }
    

    override fun getItemViewType(position: Int): Int {
        if(position == 0) {
            return TYPE_HEADER
        }
    
        return TYPE_ITEMS
    }
    

    override fun getItemViewType(position: Int): Int {
        if(position == 0) {
            return TYPE_HEADER
        } else if(position == isnumberList.size + 2) {
            return TYPE_FOOTER
        }
    
        return TYPE_ITEMS
    }
    

    【讨论】:

    • 不错。现在,当我到达按钮时,我的列表正在加载,但页脚进度条没有显示
    • 从 getPage() 方法中的 MainActivity 加载时,尝试在适配器上调用 notifyDatasetChanged()
    • 我已经在 getPage() 中调用了 notifyDatasetChanged(),正如您在我的代码中看到的那样
    • 如果您分享您的代码库,我可以尝试进一步提供帮助。
    • 经过反复试验,当我滚动到底部时,我可以看到页脚。但我不明白它是如何工作的。我正在使用更新的功能发布和更新问题
    猜你喜欢
    • 1970-01-01
    • 2014-12-14
    • 1970-01-01
    • 2015-11-07
    • 2018-08-16
    • 2019-09-21
    • 2018-02-05
    • 2015-02-28
    • 1970-01-01
    相关资源
    最近更新 更多