title: RecyclerView changes its scroll position when inside a ConstraintLayout
body: <p>I encountered an issue with <code>RecyclerView</code> when it is a child of a <code>ConstraintLayout</code>. Originally, the <code>RecyclerView</code> was somewhere deep in the view hierarchy of <code>Relative-</code>, <code>Frame-</code> and <code>LinearLeayout</code>s, and everything worked well until I decided to flatten view tree using ConstraintLayout. I noticed that each time when there is a layout change, caused by anything (window resize, data set change notification, etc), the scroll position of the <code>RecyclerView</code> is changed.</p>
  
  <p>For example, every time I show and hide soft keyboard, the content recycler view drifts by a certain amount of pixels.</p>
  
  <p>I was able to reproduce this behavior on a very simple layout: </p>
  
  <pre><code>ConstraintLayout
  |---RecyclerView
  |---Button
  |---EditText
  </code></pre>
  
  <p>If I set constraints such that <code>RecyclerView</code> is placed <strong>above</strong> any other child of <code>ConstraintLayout</code> (meaning RecyclerView has a bottom constraint), and if I use <code>LinearLayoutManager</code> with <code>reverseLayout = true</code>, I can reproduce the described above bahavior.</p>
  
  <p>How should I fix this (I don't want the scroll position to change)? Maybe there are some flags on RecyclerView and/or ConstraintLayout that I don't know of...</p>
  
  <p>Here is my <code>layout.xml</code>:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;android.support.constraint.ConstraintLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      &gt;
  
      &lt;android.support.v7.widget.RecyclerView
          android:id="@+id/recycler"
          android:layout_width="match_parent"
          android:layout_height="0dp"
          app:layout_constraintBottom_toTopOf="@+id/button"
          app:layout_constraintTop_toTopOf="parent"
          /&gt;
  
      &lt;Button
          android:id="@+id/button"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="Notify Items Changed"
          app:layout_constraintBottom_toTopOf="@+id/edit_text"
          app:layout_constraintEnd_toStartOf="parent"
          app:layout_constraintStart_toEndOf="parent"
          /&gt;
  
      &lt;EditText
          android:id="@+id/edit_text"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          app:layout_constraintBottom_toBottomOf="parent"
          /&gt;
  
  &lt;/android.support.constraint.ConstraintLayout&gt;
  </code></pre>
  
  <p>And here is code to setup <code>RecyclerView</code> in <code>Activity.onCreate()</code>:</p>
  
  
  
  <pre><code>setContentView(R.layout.activity_main)
  
  val adapter = Adapter()
  
  val layoutManager = LinearLayoutManager(this)
  layoutManager.orientation = LinearLayoutManager.VERTICAL
  layoutManager.reverseLayout = true
  
  val recycler = findViewById&lt;RecyclerView&gt;(R.id.recycler)
  recycler.layoutManager = layoutManager
  recycler.adapter = adapter
  
  recycler.addOnLayoutChangeListener { _, _, _, _, bottom, _, _, _, oldBottom -&gt;
      Log.d("TEST", "bottom=$bottom, oldBottom=$oldBottom")
  }
  
  recycler.addOnScrollListener(object : RecyclerView.OnScrollListener() {
      override fun onScrolled(recyclerView: RecyclerView?, dx: Int, dy: Int) {
          Log.d("TEST", "Scrolled: dx=$dx, dy=$dy")
          Log.d("TEST", "offset = " + recycler.computeVerticalScrollOffset())
      }
  })
  
  findViewById&lt;Button&gt;(R.id.button)
          .setOnClickListener {
              adapter.notifyDataSetChanged()
          }
  </code></pre>
  
  <p>Here is a fragment of debug logs, which were collected after several clicks on the button:</p>
  
  <pre><code>D/TEST: Scrolled: dx=0, dy=0
  D/TEST: offset = 4167
  D/TEST: bottom=1253, oldBottom=1253
  D/TEST: Scrolled: dx=0, dy=0
  D/TEST: offset = 3887
  D/TEST: bottom=1253, oldBottom=1253
  D/TEST: Scrolled: dx=0, dy=0
  D/TEST: offset = 3607
  D/TEST: bottom=1253, oldBottom=1253
  D/TEST: Scrolled: dx=0, dy=0
  D/TEST: offset = 3327
  D/TEST: bottom=1253, oldBottom=1253
  </code></pre>
  
  <p>The scroll positions is slowly changing and content is being scrolled towards the top. The shift is roughly amounts to the total height of widgets below <code>RecyclerView</code>. </p>
  
  <p>I could reproduce this behavior only when all conditions are met: </p>
  
  <ul>
  <li><code>RecyclerView</code> is positioned inside a <code>ConstraintLayout</code></li>
  <li>There are other sibling widgets below <code>RecyclerView</code></li>
  <li><code>LinearLayoutManager</code> is used with either of flags <code>reverseLayout</code> or <code>stackFromBottom</code> being set to <code>true</code>.</li>
  </ul>
  
  <p>I am using <code>ConstraintLayout</code> version is <code>1.1.2</code>.</p>