Stop social update view from stealing focus.
ContactDetailFragmentCarousel was requesting focus to set the initial offset of
the HorizontalScrollView. This was probably a hacky work around to get the
smoothScrollTo() method to work.
Instead of requesting focus, call scrollTo(). Before scrollTo() did not work
in the enableSwipe() method because HorizontalScrollView "clamp"s the offset
to the size of the width. And the size of the width was calculated based on
mEnableSwipe flag in the onMeasure() method. To fix it so scrollTo() works
within enableSwipe(), change the width calculation to also take into account
mCurrentPage which may be initialized to 1 instead of 0.
Old order
+ onMeasure() [mEnabledSwipe = false, width set for a single child]
+ enableSwipe() [mEnabledSwipe = true, width still set for a single child]
+ scrollTo() [page 1, fails because width set for a single child]
New logic
+ onMeasure() [mCurrentPage = 1, width set for 2 childs]
+ enableSwipe()
+ scrollTo() [page 1, suceeds]
Bug: 8157306
Change-Id: I3a693a0b3d43a68d251faea4b5805791f2316aaa
diff --git a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
index a66baa5..f85bd23 100644
--- a/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
+++ b/src/com/android/contacts/detail/ContactDetailFragmentCarousel.java
@@ -116,7 +116,9 @@
View child = getChildAt(0);
// If we enable swipe, then the {@link LinearLayout} child width must be the sum of the
// width of all its children fragments.
- if (mEnableSwipe) {
+ // Or the current page may already be set to something other than the first. If so,
+ // it also means there are multiple child fragments.
+ if (mEnableSwipe || mCurrentPage != 0) {
child.measure(MeasureSpec.makeMeasureSpec(
mMinFragmentWidth * MAX_FRAGMENT_VIEW_COUNT, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(screenHeight, MeasureSpec.EXACTLY));
@@ -163,11 +165,7 @@
mEnableSwipe = enable;
if (mUpdatesFragment != null) {
mUpdatesFragment.setVisibility(enable ? View.VISIBLE : View.GONE);
- if (mCurrentPage == ABOUT_PAGE) {
- mAboutFragment.requestFocus();
- } else {
- mUpdatesFragment.requestFocus();
- }
+ snapToEdge();
updateTouchInterceptors();
}
}
@@ -179,7 +177,7 @@
public void reset() {
if (mCurrentPage != ABOUT_PAGE) {
mCurrentPage = ABOUT_PAGE;
- snapToEdge();
+ snapToEdgeSmooth();
}
}
@@ -191,7 +189,7 @@
@Override
public void onClick(View v) {
mCurrentPage = ABOUT_PAGE;
- snapToEdge();
+ snapToEdgeSmooth();
}
};
@@ -199,7 +197,7 @@
@Override
public void onClick(View v) {
mCurrentPage = UPDATES_PAGE;
- snapToEdge();
+ snapToEdgeSmooth();
}
};
@@ -222,13 +220,27 @@
mLastScrollPosition = l;
}
+ /**
+ * Used to set initial scroll offset. Not smooth.
+ */
private void snapToEdge() {
- final int x = mCurrentPage == ABOUT_PAGE ? 0 : mAllowedHorizontalScrollLength;
- smoothScrollTo(x,0);
+ setScrollX(calculateHorizontalOffset());
updateTouchInterceptors();
}
/**
+ * Smooth version of snapToEdge().
+ */
+ private void snapToEdgeSmooth() {
+ smoothScrollTo(calculateHorizontalOffset(), 0);
+ updateTouchInterceptors();
+ }
+
+ private int calculateHorizontalOffset() {
+ return mCurrentPage == ABOUT_PAGE ? 0 : mAllowedHorizontalScrollLength;
+ }
+
+ /**
* Returns the desired page we should scroll to based on the current X scroll position and the
* current page.
*/
@@ -253,7 +265,7 @@
}
if (event.getAction() == MotionEvent.ACTION_UP) {
mCurrentPage = getDesiredPage();
- snapToEdge();
+ snapToEdgeSmooth();
return true;
}
return false;