Recycler view not scrolling to the top after adding new item at the top, as changes to the list adapter has not yet occurred

后端 未结 5 1472
无人及你
无人及你 2021-02-07 06:37

I am getting the new list with new item at the start in my live data and then using its data to update the adapter

viewModel.myLiveData.observe { this, Observer          


        
相关标签:
5条回答
  • 2021-02-07 06:45

    Thank you everyone for response. But the only work that did worked for me was to place a 1 second delay after executing submitList. Even though not appropriate one, But works for the following reason:

    adapter.submitList() will always take the same execution time (within milliseconds)

    I just called

    Handler().postDelayed ({
      recycler.scrollToPosition(0)
    }, 1000)
    
    0 讨论(0)
  • 2021-02-07 06:53

    submitList does its work on a background thread, so there will always be race conditions that delays can't solve. Fortunately, we can use a RecyclerView.AdapterDataObserver callback to be informed when the list calculations are complete:

    yourRecyclerViewAdapter.registerAdapterDataObserver(object: RecyclerView.AdapterDataObserver() {
        override fun onChanged() {
            recycler_view_list.scrollToPosition(0)
        }
        override fun onItemRangeRemoved(positionStart: Int, itemCount: Int) {
            recycler_view_list.scrollToPosition(0)
        }
        override fun onItemRangeMoved(fromPosition: Int, toPosition: Int, itemCount: Int) {
            recycler_view_list.scrollToPosition(0)
        }
        override fun onItemRangeInserted(positionStart: Int, itemCount: Int) {
            recycler_view_list.scrollToPosition(0)
        }
        override fun onItemRangeChanged(positionStart: Int, itemCount: Int) {
            recycler_view_list.scrollToPosition(0)
        }
        override fun onItemRangeChanged(positionStart: Int, itemCount: Int, payload: Any?) {
            recycler_view_list.scrollToPosition(0)
        }
    })
    
    viewModel.myLiveData.observe { this, Observer { myList -> 
            adapter.submitList(myList) 
    }
    
    0 讨论(0)
  • 2021-02-07 06:53

    Use this way

    viewModel.myLiveData.observe { this, Observer { myList -> 
        adapter.submitList(myList) // Assuming you are notifying adapter by notifydatasetchanged()
        recyclerView.post { recyclerView.scrollToPosition(0) }
    }
    

    Here post is giving UI Thread some time to populate Recycler with new data and then call scrollToPosition.

    0 讨论(0)
  • 2021-02-07 06:54

    You can also use

    recyclerView.smoothScrollToPosition(0);
    
    viewModel.myLiveData.observe { this, Observer { myList -> 
            adapter.submitList(myList) 
             recyclerView.smoothScrollToPosition(0);
    }
    
    0 讨论(0)
  • 2021-02-07 06:56

    Another way to Solve this Problem is wrapping the Recyclerview inside the Nested ScrollView.

     <android.support.v4.widget.NestedScrollView
        android:id="@+id/nsv_data"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
               <android.support.v7.widget.RecyclerView
                    android:id="@+id/rv"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:nestedScrollingEnabled="false"
                    tools:listitem="@layout/rv_interview_prep_row"
                    android:visibility="gone"
                    android:background="@color/white" />
    </android.support.v4.widget.NestedScrollView>
    

    Then inside your Activity or Fragment.

    viewModel.myLiveData.observe { this, Observer { myList -> 
        adapter.submitList(myList) 
        nestedScrollView.scrollTo(0,0);
    }
    
    0 讨论(0)
提交回复
热议问题