Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2552)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java

Issue 1836453003: Use a scrollable tab strip on tablets at small widths (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Tiny bit of clean up Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
index dd894353c49ee2f686c92708a82ae5aa5095b8fe..19db6a5466c87e11c49e12ffea53cc8abfbc14a8 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -30,7 +30,6 @@ import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
import org.chromium.chrome.browser.compositor.layouts.components.CompositorButton;
import org.chromium.chrome.browser.compositor.layouts.components.VirtualView;
-import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager;
import org.chromium.chrome.browser.compositor.layouts.phone.stack.StackScroller;
import org.chromium.chrome.browser.compositor.overlays.strip.TabLoadTracker.TabLoadTrackerCallback;
import org.chromium.chrome.browser.tab.Tab;
@@ -38,6 +37,7 @@ import org.chromium.chrome.browser.tabmodel.TabCreatorManager.TabCreator;
import org.chromium.chrome.browser.tabmodel.TabModel;
import org.chromium.chrome.browser.tabmodel.TabModelUtils;
import org.chromium.chrome.browser.util.MathUtils;
+import org.chromium.ui.base.DeviceFormFactor;
import org.chromium.ui.base.LocalizationUtils;
import java.util.ArrayList;
@@ -67,7 +67,7 @@ public class StripLayoutHelper {
// Animation/Timer Constants
private static final int RESIZE_DELAY_MS = 1500;
private static final int SPINNER_UPDATE_DELAY_MS = 66;
- // Degrees per milisecond.
+ // Degrees per millisecond.
private static final float SPINNER_DPMS = 0.33f;
private static final int EXPAND_DURATION_MS = 250;
private static final int ANIM_TAB_CREATED_MS = 150;
@@ -88,6 +88,7 @@ public class StripLayoutHelper {
private static final float NEW_TAB_BUTTON_CLICK_SLOP_DP = 4.f;
private static final float NEW_TAB_BUTTON_WIDTH_DP = 58.f;
private static final float NEW_TAB_BUTTON_HEIGHT_DP = 32.5f;
+ static final float FADE_FULL_OPACITY_THRESHOLD_DP = 24.f;
private static final int MESSAGE_RESIZE = 1;
private static final int MESSAGE_UPDATE_SPINNER = 2;
@@ -97,8 +98,9 @@ public class StripLayoutHelper {
private final LayoutRenderHost mRenderHost;
private TabModel mModel;
private TabCreator mTabCreator;
- private TabContentManager mTabContentManager;
- private StripStacker mStripStacker = new StaticStripStacker();
+ private StripStacker mStripStacker;
+ private CascadingStripStacker mCascadingStripStacker = new CascadingStripStacker();
+ private ScrollingStripStacker mScrollingStripStacker = new ScrollingStripStacker();
// Internal State
private StripLayoutTab[] mStripTabs = new StripLayoutTab[0];
@@ -111,9 +113,8 @@ public class StripLayoutHelper {
private final CompositorButton mNewTabButton;
// Layout Constants
- private final float mTabStackWidth;
private final float mTabOverlapWidth;
- private float mNewTabButtonWidth;
+ private final float mNewTabButtonWidth;
private final float mMinTabWidth;
private final float mMaxTabWidth;
private final float mReorderMoveStartThreshold;
@@ -141,6 +142,8 @@ public class StripLayoutHelper {
private float mRightMargin;
private final boolean mIncognito;
private float mBrightness;
+ // Whether the CascadingStripStacker should be used.
+ private boolean mShouldCascadeTabs;
// Tab menu item IDs
public static final int ID_CLOSE_ALL_TABS = 0;
@@ -155,14 +158,9 @@ public class StripLayoutHelper {
*/
public StripLayoutHelper(Context context, LayoutUpdateHost updateHost,
LayoutRenderHost renderHost, boolean incognito) {
- mTabStackWidth = TAB_STACK_WIDTH_DP;
mTabOverlapWidth = TAB_OVERLAP_WIDTH_DP;
mNewTabButtonWidth = NEW_TAB_BUTTON_WIDTH_DP;
- if (LocalizationUtils.isLayoutRtl()) {
- // In rtl let the tab nest closer to the new tab button.
- mNewTabButtonWidth -= mTabOverlapWidth / 2;
- }
mRightMargin = LocalizationUtils.isLayoutRtl() ? 0 : mNewTabButtonWidth;
mLeftMargin = LocalizationUtils.isLayoutRtl() ? mNewTabButtonWidth : 0;
mMinTabWidth = MIN_TAB_WIDTH_DP;
@@ -206,6 +204,13 @@ public class StripLayoutHelper {
int menuWidth = mContext.getResources().getDimensionPixelSize(R.dimen.menu_width);
mTabMenu.setWidth(menuWidth);
mTabMenu.setModal(true);
+
+ int screenWidthDp = context.getResources().getConfiguration().screenWidthDp;
+ mShouldCascadeTabs = screenWidthDp >= DeviceFormFactor.MINIMUM_TABLET_WIDTH_DP;
+ mStripStacker = mShouldCascadeTabs ? mCascadingStripStacker : mScrollingStripStacker;
+
+ // TODO(twellington): auto-scroll on cold start and when the tab model is switched
+ // so the selected tab is visible when !mShouldCascadeTabs.
}
/**
@@ -263,6 +268,47 @@ public class StripLayoutHelper {
}
/**
+ * @return The opacity to use for the fade on the left side of the tab strip.
+ */
+ public float getLeftFadeOpacity() {
+ return getFadeOpacity(true);
+ }
+
+ /**
+ * @return The opacity to use for the fade on the right side of the tab strip.
+ */
+ public float getRightFadeOpacity() {
+ return getFadeOpacity(false);
+ }
+
+ /**
+ * When the {@link ScrollingStripStacker} is being used, a fade is shown at the left and
+ * right edges to indicate there is tab strip content off screen. As the scroll position
+ * approaches the edge of the screen, the fade opacity is lowered.
+ *
+ * @param isLeft Whether the opacity for the left or right side should be returned.
+ * @return The opacity to use for the fade.
+ */
+ private float getFadeOpacity(boolean isLeft) {
+ if (mShouldCascadeTabs) return 0.f;
+
+ // In RTL, scroll position 0 is on the right side of the screen, whereas in LTR scroll
+ // position 0 is on the left. Account for that in the offset calculation.
+ boolean isRtl = LocalizationUtils.isLayoutRtl();
+ boolean useUnadjustedScrollOffset = isRtl != isLeft;
+ float offset = -(useUnadjustedScrollOffset ? mScrollOffset
+ : (mMinScrollOffset - mScrollOffset));
+
+ if (offset == 0.f) {
+ return 0.f;
+ } else if (offset >= FADE_FULL_OPACITY_THRESHOLD_DP) {
+ return 1.f;
+ } else {
+ return offset / FADE_FULL_OPACITY_THRESHOLD_DP;
+ }
+ }
+
+ /**
* Allows changing the visual behavior of the tabs in this stack, as specified by
* {@code stacker}.
* @param stacker The {@link StripStacker} that should specify how the tabs should be
@@ -279,21 +325,14 @@ public class StripLayoutHelper {
}
/**
- * @parm margin The width of the distance between the left edge of
- * the screen and first tab.
- */
- public void setLeftMargin(float margin) {
- mLeftMargin = margin;
- mLeftMargin += LocalizationUtils.isLayoutRtl() ? mNewTabButtonWidth : 0;
- }
-
- /**
- * @param margin The distance between the rightmost tab and the edge of the
- * screen.
+ * @param margin The distance between the last tab and the edge of the screen.
*/
- public void setRightMargin(float margin) {
- mRightMargin = margin;
- mRightMargin += LocalizationUtils.isLayoutRtl() ? 0 : mNewTabButtonWidth;
+ public void setEndMargin(float margin) {
+ if (LocalizationUtils.isLayoutRtl()) {
+ mLeftMargin = margin + mNewTabButtonWidth;
+ } else {
+ mRightMargin = margin + mNewTabButtonWidth;
+ }
}
/**
@@ -313,7 +352,10 @@ public class StripLayoutHelper {
mStripTabs[i].setHeight(mHeight);
}
- if (widthChanged) computeAndUpdateTabWidth(false);
+ if (widthChanged) {
+ computeAndUpdateTabWidth(false);
+ setShouldCascadeTabs(width >= DeviceFormFactor.MINIMUM_TABLET_WIDTH_DP);
+ }
if (mStripTabs.length > 0) mUpdateHost.requestUpdate();
// Dismiss tab menu, similar to how the app menu is dismissed on orientation change
@@ -321,6 +363,31 @@ public class StripLayoutHelper {
}
/**
+ * Should be called when the viewport width crosses the 600dp threshold. The
+ * {@link CascadingStripStacker} should be used at 600dp+, otherwise the
+ * {@link ScrollingStripStacker} should be used.
+ * @param shouldCascadeTabs Whether the {@link CascadingStripStacker} should be used.
+ */
+ void setShouldCascadeTabs(boolean shouldCascadeTabs) {
+ if (shouldCascadeTabs != mShouldCascadeTabs) {
+ mShouldCascadeTabs = shouldCascadeTabs;
+ setTabStacker(shouldCascadeTabs ? mCascadingStripStacker : mScrollingStripStacker);
+
+ // Scroll to make the selected tab visible and nearby tabs visible.
+ if (mModel.getTabAt(mModel.index()) != null) {
+ updateScrollOffsetLimits();
+ StripLayoutTab tab = findTabById(mModel.getTabAt(mModel.index()).getId());
+ float delta = calculateOffsetToMakeTabVisible(tab, true, true, true);
+ // During this resize, mMinScrollOffset will be changing, so the scroll effect
+ // cannot be properly animated. Jump to the new scroll offset instead.
+ mScrollOffset += delta;
+ }
+
+ updateStrip();
+ }
+ }
+
+ /**
* Updates all internal resources and dimensions.
* @param context The current Android {@link Context}.
*/
@@ -343,11 +410,11 @@ public class StripLayoutHelper {
/**
* Sets the {@link TabModel} that this {@link StripLayoutHelper} will visually represent.
* @param model The {@link TabModel} to visually represent.
+ * @param tabCreator The {@link TabCreator}, used to create new tabs.
*/
- public void setTabModel(TabModel model, TabContentManager manager, TabCreator tabCreator) {
+ public void setTabModel(TabModel model, TabCreator tabCreator) {
if (mModel == model) return;
mModel = model;
- mTabContentManager = manager;
mTabCreator = tabCreator;
computeAndUpdateTabOrders(false);
}
@@ -361,7 +428,7 @@ public class StripLayoutHelper {
public boolean updateLayout(long time, long dt) {
PerfTraceEvent.instant("StripLayoutHelper:updateLayout");
final boolean doneAnimating = onUpdateAnimation(time, false);
- updateStrip(time, dt);
+ updateStrip();
return doneAnimating;
}
@@ -376,6 +443,14 @@ public class StripLayoutHelper {
tabCreated(time, id, prevId, true);
} else {
updateVisualTabOrdering();
+
+ // If the tab was selected through a method other than the user tapping on the strip, it
+ // may not be currently visible. Scroll if necessary.
+ if (!mShouldCascadeTabs && !findTabById(id).isVisible()) {
+ float delta = calculateOffsetToMakeTabVisible(findTabById(id), true, true, true);
+ setScrollForScrollingTabStacker(delta, true, time);
+ }
+
mUpdateHost.requestUpdate();
}
}
@@ -443,16 +518,33 @@ public class StripLayoutHelper {
// 3. Figure out which tab needs to be visible.
StripLayoutTab fastExpandTab = findTabById(prevId);
boolean allowLeftExpand = false;
+ boolean canExpandSelectedTab = false;
if (!selected) {
fastExpandTab = tab;
allowLeftExpand = true;
}
+ if (!mShouldCascadeTabs) {
+ fastExpandTab = tab;
+ allowLeftExpand = true;
+ canExpandSelectedTab = true;
+ }
+
// 4. Scroll the stack so that the fast expand tab is visible.
if (fastExpandTab != null) {
- float delta =
- calculateOffsetToMakeTabVisible(fastExpandTab, false, allowLeftExpand, true);
- if (delta != 0.f) {
+ float delta = calculateOffsetToMakeTabVisible(
+ fastExpandTab,
+ canExpandSelectedTab,
+ allowLeftExpand,
+ true);
+
+ if (!mShouldCascadeTabs) {
+ // If the ScrollingStripStacker is being used and the new tab button is visible, go
+ // directly to the new scroll offset rather than animating. Animating the scroll
+ // causes the new tab button to disappear for a frame.
+ boolean shouldAnimate = !mNewTabButton.isVisible();
+ setScrollForScrollingTabStacker(delta, shouldAnimate, time);
+ } else if (delta != 0.f) {
mScroller.startScroll(mScrollOffset, 0, (int) delta, 0, time, EXPAND_DURATION_MS);
}
}
@@ -546,9 +638,16 @@ public class StripLayoutHelper {
// 2.b. Still scrolling, update the scroll destination here.
mScroller.setFinalX((int) (mScroller.getFinalX() + deltaX));
} else {
- // 2.c. Not scrolling. Check if we need to fast expand.
- float fastExpandDelta =
- calculateOffsetToMakeTabVisible(mInteractingTab, true, true, true);
+ // 2.c. Not scrolling. Check if we need to fast expand.
+ float fastExpandDelta;
+ if (mShouldCascadeTabs) {
+ fastExpandDelta =
+ calculateOffsetToMakeTabVisible(mInteractingTab, true, true, true);
+ } else {
+ // Non-cascaded tabs are never hidden behind each other, so there's no need to fast
+ // expand.
+ fastExpandDelta = 0.f;
+ }
if (mInteractingTab != null && fastExpandDelta != 0.f) {
if ((fastExpandDelta > 0 && deltaX > 0) || (fastExpandDelta < 0 && deltaX < 0)) {
@@ -874,9 +973,15 @@ public class StripLayoutHelper {
// 2. Compute the effective width of every tab.
float tabsWidth = 0.f;
- for (int i = 0; i < mStripTabs.length; i++) {
- final StripLayoutTab tab = mStripTabs[i];
- tabsWidth += (tab.getWidth() - mTabOverlapWidth) * tab.getWidthWeight();
+ if (mShouldCascadeTabs) {
+ for (int i = 0; i < mStripTabs.length; i++) {
+ final StripLayoutTab tab = mStripTabs[i];
+ tabsWidth += (tab.getWidth() - mTabOverlapWidth) * tab.getWidthWeight();
+ }
+ } else {
+ // When tabs aren't cascaded, they're non-animating width weight is always 1.0 so it
+ // doesn't need to be included in this calculation.
+ tabsWidth = mStripTabs.length * (mCachedTabWidth - mTabOverlapWidth);
}
// 3. Correct fencepost error in tabswidth;
@@ -994,7 +1099,7 @@ public class StripLayoutHelper {
}
}
- private void updateStrip(long time, long dt) {
+ private void updateStrip() {
if (mModel == null) return;
// TODO(dtrainor): Remove this once tabCreated() is refactored to be called even from
@@ -1010,10 +1115,12 @@ public class StripLayoutHelper {
computeTabInitialPositions();
// 3. Calculate the tab stacking.
- computeTabOffsetHelper();
+ mStripStacker.setTabOffsets(mModel.index(), mStripTabs, TAB_STACK_WIDTH_DP,
+ MAX_TABS_TO_STACK, mTabOverlapWidth, mLeftMargin, mRightMargin, mWidth,
+ mInReorderMode);
// 4. Calculate which tabs are visible.
- mStripStacker.performOcclusionPass(mModel.index(), mStripTabs);
+ mStripStacker.performOcclusionPass(mModel.index(), mStripTabs, mWidth);
// 5. Create render list.
createRenderList();
@@ -1052,91 +1159,6 @@ public class StripLayoutHelper {
}
}
- private void computeTabOffsetHelper() {
- final int selIndex = mModel.index();
-
- // 1. Calculate the size of the selected tab. This is used later to figure out how
- // occluded the tabs are.
- final StripLayoutTab selTab = selIndex >= 0 ? mStripTabs[selIndex] : null;
- final float selTabWidth = selTab != null ? selTab.getWidth() : 0;
- final float selTabVisibleSize = selTabWidth - mTabStackWidth - mTabOverlapWidth;
-
- for (int i = 0; i < mStripTabs.length; i++) {
- StripLayoutTab tab = mStripTabs[i];
-
- float posX = tab.getIdealX();
-
- // 2. Calculate how many tabs are stacked on the left or the right, giving us an idea
- // of where we can stack this current tab.
- int leftStackCount = (i < selIndex) ? Math.min(i, MAX_TABS_TO_STACK)
- : Math.min(MAX_TABS_TO_STACK, selIndex)
- + Math.min(MAX_TABS_TO_STACK, i - selIndex);
-
- int rightStackCount = (i >= selIndex)
- ? Math.min(mStripTabs.length - 1 - i, MAX_TABS_TO_STACK)
- : Math.min(mStripTabs.length - 1 - selIndex, MAX_TABS_TO_STACK)
- + Math.min(selIndex - i, MAX_TABS_TO_STACK);
-
- if (LocalizationUtils.isLayoutRtl()) {
- int oldLeft = leftStackCount;
- leftStackCount = rightStackCount;
- rightStackCount = oldLeft;
- }
-
- // 3. Calculate the proper draw position for the tab. Clamp based on stacking
- // rules.
- float minDrawX = mTabStackWidth * leftStackCount + mLeftMargin;
- float maxDrawX = mWidth - mTabStackWidth * rightStackCount - mRightMargin;
-
- float drawX =
- MathUtils.clamp(posX + tab.getOffsetX(), minDrawX, maxDrawX - tab.getWidth());
-
- // TODO(dtrainor): Don't set drawX if the tab is closing?
- tab.setDrawX(drawX);
- tab.setDrawY(tab.getOffsetY());
-
- // 4. Calculate how visible this tab is.
- float visiblePercentage = 1.f;
- if (i != selIndex) {
- final float effectiveTabWidth = Math.max(tab.getWidth(), 1.f);
- final boolean leftStack =
- LocalizationUtils.isLayoutRtl() ? i > selIndex : i < selIndex;
- final float minVisible = !leftStack ? minDrawX + selTabVisibleSize : minDrawX;
- final float maxVisible = leftStack ? maxDrawX - selTabVisibleSize : maxDrawX;
-
- final float clippedTabWidth =
- Math.min(posX + effectiveTabWidth, maxVisible) - Math.max(posX, minVisible);
- visiblePercentage = MathUtils.clamp(clippedTabWidth / effectiveTabWidth, 0.f, 1.f);
- }
- tab.setVisiblePercentage(visiblePercentage);
-
- // 5. Calculate which index we start sliding content for.
- // When reordering, we don't want to slide the content of the adjacent tabs.
- int contentOffsetIndex = mInReorderMode ? selIndex + 1 : selIndex;
-
- // 6. Calculate how much the tab is overlapped on the left side or right for RTL.
- float hiddenAmount = 0.f;
- if (i > contentOffsetIndex && i > 0 && mStripStacker.canSlideTitleText()) {
- // 6.a. Get the effective right edge of the previous tab.
- final StripLayoutTab prevTab = mStripTabs[i - 1];
- final float prevLayoutWidth =
- (prevTab.getWidth() - mTabOverlapWidth) * prevTab.getWidthWeight();
- float prevTabRight = prevTab.getDrawX();
- if (!LocalizationUtils.isLayoutRtl()) prevTabRight += prevLayoutWidth;
-
- // 6.b. Subtract our current draw X from the previous tab's right edge and
- // get the percentage covered.
- hiddenAmount = Math.max(prevTabRight - drawX, 0);
- if (LocalizationUtils.isLayoutRtl()) {
- // Invert The amount because we're RTL.
- hiddenAmount = prevLayoutWidth - hiddenAmount;
- }
- }
-
- tab.setContentOffsetX(hiddenAmount);
- }
- }
-
private void createRenderList() {
// 1. Figure out how many tabs will need to be rendered.
int renderCount = 0;
@@ -1164,28 +1186,21 @@ public class StripLayoutHelper {
mNewTabButton.setVisible(false);
return;
}
- mNewTabButton.setVisible(true);
- float leftEdge = mWidth - mRightMargin;
- float rightEdge = mLeftMargin;
+ // 1. Get offset from strip stacker.
+ float offset = mStripStacker.computeNewTabButtonOffset(mStripTabs,
+ mTabOverlapWidth, mLeftMargin, mRightMargin, mWidth, mNewTabButtonWidth);
- for (int i = 0; i < mStripTabs.length; i++) {
- StripLayoutTab tab = mStripTabs[i];
- float layoutWidth = (tab.getWidth() - mTabOverlapWidth) * tab.getWidthWeight();
- rightEdge = Math.max(tab.getDrawX() + layoutWidth, rightEdge);
- leftEdge = Math.min(tab.getDrawX(), leftEdge);
+ // 2. Hide the new tab button if it's not visible on the screen.
+ boolean isRtl = LocalizationUtils.isLayoutRtl();
+ if ((isRtl && offset + mNewTabButtonWidth < 0) || (!isRtl && offset > mWidth)) {
+ mNewTabButton.setVisible(false);
+ return;
}
- rightEdge = Math.min(rightEdge + mTabOverlapWidth, mWidth - mRightMargin);
- leftEdge = Math.max(leftEdge, mLeftMargin);
-
- rightEdge -= mTabOverlapWidth / 2;
+ mNewTabButton.setVisible(true);
// 3. Position the new tab button.
- if (!LocalizationUtils.isLayoutRtl()) {
- mNewTabButton.setX(rightEdge);
- } else {
- mNewTabButton.setX(leftEdge - mNewTabButtonWidth);
- }
+ mNewTabButton.setX(offset);
}
private float calculateOffsetToMakeTabVisible(StripLayoutTab tab, boolean canExpandSelectedTab,
@@ -1219,10 +1234,16 @@ public class StripLayoutHelper {
// 4. Return the proper deltaX that has to be applied to the current scroll to see the
// tab.
- if (mScrollOffset < optimalLeft && canExpandLeft) {
+ if (mShouldCascadeTabs) {
+ if (mScrollOffset < optimalLeft && canExpandLeft) {
+ return optimalLeft - mScrollOffset;
+ } else if (mScrollOffset > optimalRight && canExpandRight) {
+ return optimalRight - mScrollOffset;
+ }
+ } else {
+ // If tabs are not cascaded, the entire tab strip scrolls and the strip should be
+ // scrolled to the optimal left offset.
return optimalLeft - mScrollOffset;
- } else if (mScrollOffset > optimalRight && canExpandRight) {
- return optimalRight - mScrollOffset;
}
// 5. We don't have to do anything. Return no delta.
@@ -1286,9 +1307,14 @@ public class StripLayoutHelper {
TabModelUtils.setIndex(
mModel, TabModelUtils.getTabIndexById(mModel, mInteractingTab.getId()));
- // 5. Fast expand to make sure this tab is visible.
- float fastExpandDelta = calculateOffsetToMakeTabVisible(mInteractingTab, true, true, true);
- mScroller.startScroll(mScrollOffset, 0, (int) fastExpandDelta, 0, time, EXPAND_DURATION_MS);
+ // 5. Fast expand to make sure this tab is visible. If tabs are not cascaded, the selected
+ // tab will already be visible, so there's no need to fast expand to make it visible.
+ if (mShouldCascadeTabs) {
+ float fastExpandDelta =
+ calculateOffsetToMakeTabVisible(mInteractingTab, true, true, true);
+ mScroller.startScroll(mScrollOffset, 0, (int) fastExpandDelta, 0, time,
+ EXPAND_DURATION_MS);
+ }
// 6. Request an update.
mUpdateHost.requestUpdate();
@@ -1583,6 +1609,16 @@ public class StripLayoutHelper {
mTabMenu.show();
}
+ private void setScrollForScrollingTabStacker(float delta, boolean shouldAnimate, long time) {
+ if (delta == 0.f) return;
+
+ if (shouldAnimate) {
+ mScroller.startScroll(mScrollOffset, 0, (int) delta, 0, time, EXPAND_DURATION_MS);
+ } else {
+ mScrollOffset += delta;
+ }
+ }
+
/**
* @return true if the tab menu is showing
*/
@@ -1598,4 +1634,62 @@ public class StripLayoutHelper {
public void clickTabMenuItem(int menuItemId) {
mTabMenu.performItemClick(menuItemId);
}
+
+ /**
+ * @return Whether the {@link CascadingStripStacker} is being used.
+ */
+ @VisibleForTesting
+ boolean shouldCascadeTabs() {
+ return mShouldCascadeTabs;
+ }
+
+ /**
+ * @return The with of the tab strip.
+ */
+ @VisibleForTesting
+ float getWidth() {
+ return mWidth;
+ }
+
+ /**
+ * @return The strip's current scroll offset.
+ */
+ @VisibleForTesting
+ int getScrollOffset() {
+ return mScrollOffset;
+ }
+
+ /**
+ * @return The strip's minimum scroll offset.
+ */
+ @VisibleForTesting
+ float getMinimumScrollOffset() {
+ return mMinScrollOffset;
+ }
+
+ /**
+ * Set the scroll offset. Should only be used for testing.
+ * @param scrollOffset The scroll offset.
+ */
+ @VisibleForTesting
+ void setScrollOffsetForTesting(int scrollOffset) {
+ mScrollOffset = scrollOffset;
+ updateStrip();
+ }
+
+ /**
+ * @return An array containing the StripLayoutTabs.
+ */
+ @VisibleForTesting
+ StripLayoutTab[] getStripLayoutTabs() {
+ return mStripTabs;
+ }
+
+ /**
+ * @return The amount tabs overlap.
+ */
+ @VisibleForTesting
+ float getTabOverlapWidth() {
+ return mTabOverlapWidth;
+ }
}

Powered by Google App Engine
This is Rietveld 408576698