Fixing issue where the prediction bar could be misplaced after installing an app.

- When the adapter changes, we didn't update the scroll position that the prediction
  bar tracks, which caused it to be misplaced.  This forces a refresh of that scroll
  position to the current state whenever an app is removed or added.
diff --git a/src/com/android/launcher3/AppsContainerRecyclerView.java b/src/com/android/launcher3/AppsContainerRecyclerView.java
index 3952923..34e621a 100644
--- a/src/com/android/launcher3/AppsContainerRecyclerView.java
+++ b/src/com/android/launcher3/AppsContainerRecyclerView.java
@@ -120,6 +120,24 @@
         mApps = apps;
     }
 
+    @Override
+    public void setAdapter(Adapter adapter) {
+        // Register a change listener to update the scroll position state whenever the data set
+        // changes.
+        adapter.registerAdapterDataObserver(new AdapterDataObserver() {
+            @Override
+            public void onChanged() {
+                post(new Runnable() {
+                    @Override
+                    public void run() {
+                        refreshCurScrollPosition();
+                    }
+                });
+            }
+        });
+        super.setAdapter(adapter);
+    }
+
     /**
      * Sets the number of apps per row in this recycler view.
      */
@@ -369,13 +387,7 @@
         }
 
         // We need to workaround the RecyclerView to get the right scroll position
-        List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
-        getCurScrollState(mScrollPosState, items);
-        if (mScrollPosState.rowIndex != -1) {
-            int scrollY = getPaddingTop() + (mScrollPosState.rowIndex * mScrollPosState.rowHeight) +
-                    mPredictionBarHeight - mScrollPosState.rowTopOffset;
-            updateScrollY(scrollY);
-        }
+        refreshCurScrollPosition();
 
         // Scroll to the view at the position, anchored at the top of the screen. We call the scroll
         // method on the LayoutManager directly since it is not exposed by RecyclerView.
@@ -465,6 +477,19 @@
     }
 
     /**
+     * Forces a refresh of the scroll position to any scroll listener.
+     */
+    private void refreshCurScrollPosition() {
+        List<AlphabeticalAppsList.AdapterItem> items = mApps.getAdapterItems();
+        getCurScrollState(mScrollPosState, items);
+        if (mScrollPosState.rowIndex != -1) {
+            int scrollY = getPaddingTop() + (mScrollPosState.rowIndex * mScrollPosState.rowHeight) +
+                    mPredictionBarHeight - mScrollPosState.rowTopOffset;
+            updateScrollY(scrollY);
+        }
+    }
+
+    /**
      * Returns the current scroll state.
      */
     private void getCurScrollState(ScrollPositionState stateOut,
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index 57ccff0..989026e 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -82,11 +82,11 @@
     private int mNumAppsPerRow;
     private int mNumPredictedAppsPerRow;
     // This coordinate is relative to this container view
-    private Point mBoundsCheckLastTouchDownPos = new Point(-1, -1);
+    private final Point mBoundsCheckLastTouchDownPos = new Point(-1, -1);
     // This coordinate is relative to its parent
-    private Point mIconLastTouchPos = new Point();
-    // This coordinate is used to proxy click and long-click events
-    private Point mPredictionIconTouchDownPos = new Point();
+    private final Point mIconLastTouchPos = new Point();
+    // This coordinate is used to proxy click and long-click events to the prediction bar icons
+    private final Point mPredictionIconTouchDownPos = new Point();
     private int mContentMarginStart;
     // Normal container insets
     private int mContainerInset;