OSDN Git Service

Fix scroll amount calculation in ViewRootImpl
authorChong Zhang <chz@google.com>
Thu, 2 Jun 2016 19:56:54 +0000 (12:56 -0700)
committerChong Zhang <chz@google.com>
Thu, 2 Jun 2016 20:33:40 +0000 (13:33 -0700)
When calculating scroll amount, we should check whehter focus
is visible using before-scrolling position.

It's possible that the view is already scrolled, then visible
insets changes (eg. IME went away). Previous scroll position
still makes the focus visible, but it will leave the focus
in a bad position when it should be scrolled back.

bug: 29025892
Change-Id: I091f16bebc4c1e5ba831616c51ab2ac75d4c4b3c

core/java/android/view/ViewRootImpl.java

index 0d648c1..4742818 100644 (file)
@@ -3078,16 +3078,22 @@ public final class ViewRootImpl implements ViewParent,
                             // best is probably just to leave things as-is.
                             if (DEBUG_INPUT_RESIZE) Log.v(mTag,
                                     "Too tall; leaving scrollY=" + scrollY);
-                        } else if ((mTempRect.top-scrollY) < vi.top) {
-                            scrollY -= vi.top - (mTempRect.top-scrollY);
+                        }
+                        // Next, check whether top or bottom is covered based on the non-scrolled
+                        // position, and calculate new scrollY (or set it to 0).
+                        // We can't keep using mScrollY here. For example mScrollY is non-zero
+                        // due to IME, then IME goes away. The current value of mScrollY leaves top
+                        // and bottom both visible, but we still need to scroll it back to 0.
+                        else if (mTempRect.top < vi.top) {
+                            scrollY = mTempRect.top - vi.top;
                             if (DEBUG_INPUT_RESIZE) Log.v(mTag,
                                     "Top covered; scrollY=" + scrollY);
-                        } else if ((mTempRect.bottom-scrollY)
-                                > (mView.getHeight()-vi.bottom)) {
-                            scrollY += (mTempRect.bottom-scrollY)
-                                    - (mView.getHeight()-vi.bottom);
+                        } else if (mTempRect.bottom > (mView.getHeight()-vi.bottom)) {
+                            scrollY = mTempRect.bottom - (mView.getHeight()-vi.bottom);
                             if (DEBUG_INPUT_RESIZE) Log.v(mTag,
                                     "Bottom covered; scrollY=" + scrollY);
+                        } else {
+                            scrollY = 0;
                         }
                         handled = true;
                     }