Home > Back-end >  RecyclerView Snap Can't Get First Item Position
RecyclerView Snap Can't Get First Item Position

Time:08-12

So I just want to save quote to the room database. It works fine for the other positions(2,3...) but I can't save the first item position.

private fun setSnapHelper(layoutManager: LinearLayoutManager) {
    val snapHelper: SnapHelper = LinearSnapHelper()
    snapHelper.attachToRecyclerView(binding.recyclerView)

    binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
        override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
            super.onScrollStateChanged(recyclerView, newState)
            if (newState == RecyclerView.SCROLL_STATE_IDLE) {
                val centerView = snapHelper.findSnapView(layoutManager)
                val pos = (layoutManager).getPosition(centerView!!)

                val quote = quoteAdapter.differ.currentList[pos]
                Log.e(TAG, "Pos: $pos")

                fabOnClick(quote)
            }
        }
    })
}

An recyclerview setup ->

private fun setupRecyclerView() {
    quoteAdapter = QuoteAdapter()
    binding.recyclerView.apply {
        adapter = quoteAdapter
        layoutManager =
            LinearLayoutManager(view?.context, LinearLayoutManager.HORIZONTAL, false)
        setSnapHelper(layoutManager as LinearLayoutManager)
    }
}

Here's onClick

private fun fabOnClick(quote: Quote) {
    viewModel.saved.observe(viewLifecycleOwner) {
        isLiked = it
        binding.fab.setOnClickListener {
            if (isLiked) {

                viewModel.deleteQuote(quote)
                Toast.makeText(context, "Deleted", Toast.LENGTH_SHORT).show()
            } else {

                viewModel.saveQuote(quote)
                isLiked = true
                Toast.makeText(context, "Liked", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

I know the problem. If I don't swipe the screen, addonScrollListener won't work. It detects the position if I scroll too far not to go to the second item. But if I click to fab for save the quote without scrolling it doesn't detect the position. I can't find the solution.

CodePudding user response:

I think you have to change implementation of onScrollStateChanged

try,

binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
    override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
        super.onScrollStateChanged(recyclerView, newState)
        if (newState == RecyclerView.SCROLL_STATE_IDLE) {
            val pos = (binding.recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()

            val quote = quoteAdapter.differ.currentList[pos]
            Log.e(TAG, "Pos: $pos")

            fabOnClick(quote)
        }
    }
})

CodePudding user response:

Instead of listening to your recycler view, you can create a listener in your adapter and invoke it when the bind method works. It will be triggered for each item that is visible on the screen.

class MyPostAdapter : BaseAdapter<IGPost, MyPostAdapter.MyPostViewHolder>() {

val itemlistener:OnItemSeeListener

inner class MyPostViewHolder(private val itemBinding: ItemMyPostBinding) :
    ViewHolder<IGPost>(itemBinding) {

    override fun bind(item: IGPost?) {
        itemlistener.invoke()
    }
}

override fun areContentsTheSame(oldItem: IGPost, newItem: IGPost) =
    oldItem.imageVersions == newItem.imageVersions

override fun areItemsTheSame(oldItem: IGPost, newItem: IGPost) =
    oldItem.id == newItem.id}
  • Related