ABDUAHAD
ABDUAHAD

Reputation: 343

Why LinearLayoutManager.findFirstVisibleItemPosition() of the RecyclerView allways returns 0?

I want to get an item position of first visible of the RecyclerView. For LayountManager of the RecyclerView, I'm using LinearLayoutManager. To get item position of first visible of the RecyclerView I am using LinearLayoutManager.findFirstVisibleItemPosition(), but it always returns 0.

private lateinit var recyclerView: RecyclerView
private lateinit var progressBar: ProgressBar
private var arrayList:List<ContentWithCategory> = ArrayList()
private lateinit var viewModel: ContentsViewModel
private lateinit var adapter: ContentsAdapter
private lateinit var title:String
private var last_content_id:Int = 0
private var category_id:Int =0

override fun onAttach(context: Context?) {
    super.onAttach(context)
    viewModel= ViewModelProviders.of(this).get(ContentsViewModel::class.java)
}

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val view= inflater.inflate(R.layout.fragment_contents, container, false)
    progressBar=view.findViewById<ProgressBar>(R.id.progressLine)
    recyclerView=view.findViewById<RecyclerView>(R.id.recyclerView)
    recyclerView.setHasFixedSize(true)
    recyclerView.itemAnimator= DefaultItemAnimator()
    viewModel.findContentsByID(category_id).observe(this, Observer<List<ContentWithCategory>>{
        arrayList=it
        adapter=ContentsAdapter(context!!,arrayList,this)
        recyclerView.adapter = adapter
        if(category_id != 0){
            for(i in 0..arrayList.size-1){
                val item = arrayList.get(i)
                if(item.id==last_content_id){
                    (recyclerView.layoutManager as LinearLayoutManager).scrollToPositionWithOffset(i, view.getTop())
                    break
                }
            }
        }
    })
    return view
}

override fun onDestroy() {
    super.onDestroy()
    val position:Int=(recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
    val data=arrayList.get(position)
    last_content_id=data.id
    (ViewModelProviders.of(this).get(CategoryViewModel::class.java)).setHistory(data.id,data.category_id)
}

(recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition() allways returns 0

Upvotes: 4

Views: 327

Answers (3)

Rahul Khurana
Rahul Khurana

Reputation: 8834

Call it before super.onDestroy().

Result code should be:

override fun onDestroy() {
    val position:Int=(recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
    val data=arrayList.get(position)
    last_content_id=data.id
    (ViewModelProviders.of(this).get(CategoryViewModel::class.java)).setHistory(data.id,data.category_id)
    super.onDestroy()
}

EDIT

According to the documentation

Returns the adapter position of the first visible view. This position does not include adapter changes that were dispatched after the last layout pass.

Upvotes: 2

UrosKekovic
UrosKekovic

Reputation: 970

Try to change onDestroy(), so you call super.onDestroy() when you are done with saving state.

override fun onDestroy() {
    val position:Int=(recyclerView.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
    val data=arrayList.get(position)
    last_content_id=data.id 
    (ViewModelProviders.of(this).get(CategoryViewModel::class.java)) .setHistory(data.id,data.category_id)

    super.onDestroy()
}

Upvotes: 1

Artem Botnev
Artem Botnev

Reputation: 2427

Specify adapter

init {
    setHasStableIds(true)
}

and

override fun getItemId(position: Int) = position.toLong()

Upvotes: 1

Related Questions