I have a simple project displaying user text messages. I am currently not able to scroll the RecyclerView to the last received text message.
My recyclerView is inside a very simple activity using the Coordinator layout:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" android:background="@color/background" tools:context="com.myproject.myproject.MessageActivity"> <android.support.design.widget.AppBarLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="?attr/colorPrimary" app:popupTheme="@style/AppTheme.PopupOverlay"/> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_message" /> </android.support.design.widget.CoordinatorLayout> And the content_message.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:descendantFocusability="beforeDescendants" android:focusable="true" android:focusableInTouchMode="true" android:orientation="vertical" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:context="com.textbutler.textbutler.MessageActivity" tools:showIn="@layout/activity_message"> <!-- some views here --> <android.support.v7.widget.RecyclerView android:id="@+id/content_text" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:scrollbars="vertical" /> <!-- some views here --> </LinearLayout> The activity load the data through a basic loader. I force the access to the recyclerview on the UI thread and with a delay (just in case)
public class MessageActivity extends AppCompatActivity { private static final int URL_LOADER = 0; private RecyclerView recyclerView; private LinearLayoutManager layoutManager; private MessageAdapter adapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_message); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); getSupportActionBar().setDisplayHomeAsUpEnabled(true); initializeList(savedInstanceState); } private void initializeList(Bundle savedInstanceState) { if (recyclerView == null) { recyclerView = (RecyclerView) findViewById(R.id.content_text); if (recyclerView == null) return; if (layoutManager == null) { layoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false); layoutManager.setReverseLayout(true); layoutManager.setStackFromEnd(true); } recyclerView.setLayoutManager(layoutManager); final Activity me = this; if (adapter == null) { adapter = new MessageAdapter(new ObservableCallback() { @Override public void callback() { // this function is called right after the recyclerview received notifyDataSetChanged new Handler().postDelayed(new Runnable() { @Override public void run() { me.runOnUiThread(new Runnable() { @Override public void run() { Log.d("ScrollingUI", "scrolltoposition " + adapter.getItemCount()); recyclerView.scrollToPosition(adapter.getItemCount() - 1); } }); } }, 1000); } }); SMSByUserLoader loader = new SMSByUserLoader(this, adapter); getSupportLoaderManager().initLoader(URL_LOADER, savedInstanceState, loader); } recyclerView.setAdapter(adapter); } } }
When I run this code, the RecyclerView is perfectly filled. After a second I have the correct log but the view does not changed. I already found various answers to this issue, but none of them seems to work in my case.
Scrolling in the RecyclerView perfectly works.