diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml index fad8c95039..8e985bdd20 100644 --- a/res/values-sw720dp/dimens.xml +++ b/res/values-sw720dp/dimens.xml @@ -28,6 +28,7 @@ 24dp 20dp 32dp + 32dp 110dp 48dp diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 098c69465d..e02ee8ad0f 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -24,6 +24,8 @@ 7dp 8dp + + 24dp 16dp 10.77dp @@ -58,13 +60,9 @@ 56dp 20dp - 36dp + 32dp 16dp - - 10sp - 1sp - 13dp 24dp @@ -229,7 +227,9 @@ 8dp 16dp 8dp - 22dp + 28dp + 0dp + 28dp 30dp diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 0b07c952bb..8da4f053df 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -24,6 +24,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; import android.graphics.drawable.Drawable; +import android.text.InputType; import android.text.TextUtils; import android.util.AttributeSet; import android.view.LayoutInflater; @@ -49,6 +50,8 @@ public abstract class ButtonDropTarget extends TextView private static final int[] sTempCords = new int[2]; private static final int DRAG_VIEW_DROP_DURATION = 285; private static final float DRAG_VIEW_HOVER_OVER_OPACITY = 0.65f; + private static final int MAX_LINES_TEXT_MULTI_LINE = 2; + private static final int MAX_LINES_TEXT_SINGLE_LINE = 1; public static final int TOOLTIP_DEFAULT = 0; public static final int TOOLTIP_LEFT = 1; @@ -72,6 +75,8 @@ public abstract class ButtonDropTarget extends TextView protected CharSequence mText; protected Drawable mDrawable; private boolean mTextVisible = true; + private boolean mIconVisible = true; + private boolean mTextMultiLine = true; private PopupWindow mToolTip; private int mToolTipLocation; @@ -109,8 +114,7 @@ public abstract class ButtonDropTarget extends TextView // drawableLeft and drawableStart. mDrawable = getContext().getDrawable(resId).mutate(); mDrawable.setTintList(getTextColors()); - centerIcon(); - setCompoundDrawablesRelative(mDrawable, null, null, null); + updateIconVisibility(); } public void setDropTargetBar(DropTargetBar dropTargetBar) { @@ -306,13 +310,49 @@ public abstract class ButtonDropTarget extends TextView if (mTextVisible != isVisible || !TextUtils.equals(newText, getText())) { mTextVisible = isVisible; setText(newText); - centerIcon(); - setCompoundDrawablesRelative(mDrawable, null, null, null); - int drawablePadding = mTextVisible ? mDrawablePadding : 0; - setCompoundDrawablePadding(drawablePadding); + updateIconVisibility(); } } + /** + * Display button text over multiple lines when isMultiLine is true, single line otherwise. + */ + public void setTextMultiLine(boolean isMultiLine) { + if (mTextMultiLine != isMultiLine) { + mTextMultiLine = isMultiLine; + setSingleLine(!isMultiLine); + setMaxLines(isMultiLine ? MAX_LINES_TEXT_MULTI_LINE : MAX_LINES_TEXT_SINGLE_LINE); + int inputType = InputType.TYPE_CLASS_TEXT; + if (isMultiLine) { + inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE; + + } + setInputType(inputType); + } + } + + protected boolean isTextMultiLine() { + return mTextMultiLine; + } + + /** + * Sets the button icon visible when isVisible is true, hides it otherwise. + */ + public void setIconVisible(boolean isVisible) { + if (mIconVisible != isVisible) { + mIconVisible = isVisible; + updateIconVisibility(); + } + } + + private void updateIconVisibility() { + if (mIconVisible) { + centerIcon(); + } + setCompoundDrawablesRelative(mIconVisible ? mDrawable : null, null, null, null); + setCompoundDrawablePadding(mIconVisible && mTextVisible ? mDrawablePadding : 0); + } + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); @@ -324,40 +364,6 @@ public abstract class ButtonDropTarget extends TextView hideTooltip(); } - - /** - * Reduce the size of the text until it fits or reaches a minimum. - * - * The minimum size is defined by {@code R.dimen.button_drop_target_min_text_size} and - * it diminishes by intervals defined by - * {@code R.dimen.button_drop_target_resize_text_increment} - * This functionality is very similar to the option - * {@link TextView#setAutoSizeTextTypeWithDefaults(int)} but can't be used in this view because - * the layout width is {@code WRAP_CONTENT}. - * - * @param availableWidth Available width in the button to fit the text, used in - * {@code ButtonDropTarget#isTextTruncated(int)} - * @return The biggest text size in SP that makes the text fit or if the text can't fit returns - * the min available value - */ - public float resizeTextToFit(int availableWidth) { - float minSize = Utilities.pxToSp(getResources() - .getDimensionPixelSize(R.dimen.button_drop_target_min_text_size)); - float step = Utilities.pxToSp(getResources() - .getDimensionPixelSize(R.dimen.button_drop_target_resize_text_increment)); - float textSize = Utilities.pxToSp(getTextSize()); - - while (textSize > minSize) { - if (isTextTruncated(availableWidth)) { - textSize -= step; - setTextSize(textSize); - } else { - return textSize; - } - } - return minSize; - } - public boolean isTextTruncated(int availableWidth) { availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth() + getCompoundDrawablePadding()); diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 96aa1c8632..e088efa53e 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -108,6 +108,7 @@ public class DeviceProfile { public float workspaceSpringLoadShrunkTop; public float workspaceSpringLoadShrunkBottom; public final int workspaceSpringLoadedBottomSpace; + public final int workspaceSpringLoadedMinNextPageVisiblePx; private final int extraSpace; public int workspaceTopPadding; @@ -214,6 +215,8 @@ public class DeviceProfile { public int dropTargetHorizontalPaddingPx; public int dropTargetVerticalPaddingPx; public int dropTargetGapPx; + public int dropTargetButtonWorkspaceEdgeGapPx; + public int dropTargetButtonScreenEdgeGapPx; // Insets private final Rect mInsets = new Rect(); @@ -343,9 +346,15 @@ public class DeviceProfile { dropTargetVerticalPaddingPx = res.getDimensionPixelSize( R.dimen.drop_target_button_drawable_vertical_padding); dropTargetGapPx = res.getDimensionPixelSize(R.dimen.drop_target_button_gap); + dropTargetButtonWorkspaceEdgeGapPx = res.getDimensionPixelSize( + R.dimen.drop_target_button_workspace_edge_gap); + dropTargetButtonScreenEdgeGapPx = res.getDimensionPixelSize( + R.dimen.drop_target_button_screen_edge_gap); workspaceSpringLoadedBottomSpace = res.getDimensionPixelSize(R.dimen.dynamic_grid_min_spring_loaded_space); + workspaceSpringLoadedMinNextPageVisiblePx = res.getDimensionPixelSize( + R.dimen.dynamic_grid_spring_loaded_min_next_space_visible); workspaceCellPaddingXPx = res.getDimensionPixelSize(R.dimen.dynamic_grid_cell_padding_x); @@ -501,7 +510,7 @@ public class DeviceProfile { */ private int calculateQsbWidth() { if (isQsbInline) { - int columns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; + int columns = getPanelCount() * inv.numColumns; return getIconToIconWidthForColumns(columns) - iconSizePx * numShownHotseatIcons - hotseatBorderSpace * numShownHotseatIcons; @@ -954,13 +963,6 @@ public class DeviceProfile { return workspaceSpringLoadShrunkBottom; } - /** - * Gets the minimum visible amount of the next workspace page when in the spring-loaded state. - */ - private float getWorkspaceSpringLoadedMinimumNextPageVisible() { - return getCellSize().x / 2f; - } - /** * Gets the scale of the workspace for the spring-loaded edit state. */ @@ -972,8 +974,7 @@ public class DeviceProfile { // Reduce scale if next pages would not be visible after scaling the workspace int workspaceWidth = availableWidthPx; float scaledWorkspaceWidth = workspaceWidth * scale; - float maxAvailableWidth = - workspaceWidth - (2 * getWorkspaceSpringLoadedMinimumNextPageVisible()); + float maxAvailableWidth = workspaceWidth - (2 * workspaceSpringLoadedMinNextPageVisiblePx); if (scaledWorkspaceWidth > maxAvailableWidth) { scale *= maxAvailableWidth / scaledWorkspaceWidth; } @@ -1412,11 +1413,19 @@ public class DeviceProfile { writer.println(prefix + pxToDpStr("dropTargetBarSizePx", dropTargetBarSizePx)); writer.println( prefix + pxToDpStr("dropTargetBarBottomMarginPx", dropTargetBarBottomMarginPx)); + writer.println(prefix + pxToDpStr("dropTargetButtonWorkspaceEdgeGapPx", + dropTargetButtonWorkspaceEdgeGapPx)); + writer.println(prefix + pxToDpStr("dropTargetButtonScreenEdgeGapPx", + dropTargetButtonScreenEdgeGapPx)); writer.println( prefix + pxToDpStr("workspaceSpringLoadShrunkTop", workspaceSpringLoadShrunkTop)); writer.println(prefix + pxToDpStr("workspaceSpringLoadShrunkBottom", workspaceSpringLoadShrunkBottom)); + writer.println(prefix + pxToDpStr("workspaceSpringLoadedBottomSpace", + workspaceSpringLoadedBottomSpace)); + writer.println(prefix + pxToDpStr("workspaceSpringLoadedMinNextPageVisiblePx", + workspaceSpringLoadedMinNextPageVisiblePx)); writer.println( prefix + pxToDpStr("getWorkspaceSpringLoadScale()", getWorkspaceSpringLoadScale())); } diff --git a/src/com/android/launcher3/DropTargetBar.java b/src/com/android/launcher3/DropTargetBar.java index 2e3f26c7d0..6a8ba1bec4 100644 --- a/src/com/android/launcher3/DropTargetBar.java +++ b/src/com/android/launcher3/DropTargetBar.java @@ -39,8 +39,6 @@ import com.android.launcher3.dragndrop.DragController.DragListener; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.testing.TestProtocol; -import java.util.Arrays; - /* * The top bar containing various drop targets: Delete/App Info/Uninstall. */ @@ -53,6 +51,8 @@ public class DropTargetBar extends FrameLayout private final Runnable mFadeAnimationEndRunnable = () -> updateVisibility(DropTargetBar.this); + private final Launcher mLauncher; + @ViewDebug.ExportedProperty(category = "launcher") protected boolean mDeferOnDragEnd; @@ -60,16 +60,19 @@ public class DropTargetBar extends FrameLayout protected boolean mVisible = false; private ButtonDropTarget[] mDropTargets; + private ButtonDropTarget[] mTempTargets; private ViewPropertyAnimator mCurrentAnimation; private boolean mIsVertical = true; public DropTargetBar(Context context, AttributeSet attrs) { super(context, attrs); + mLauncher = Launcher.getLauncher(context); } public DropTargetBar(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); + mLauncher = Launcher.getLauncher(context); } @Override @@ -80,12 +83,13 @@ public class DropTargetBar extends FrameLayout mDropTargets[i] = (ButtonDropTarget) getChildAt(i); mDropTargets[i].setDropTargetBar(this); } + mTempTargets = new ButtonDropTarget[getChildCount()]; } @Override public void setInsets(Rect insets) { FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile(); + DeviceProfile grid = mLauncher.getDeviceProfile(); mIsVertical = grid.isVerticalBarLayout(); lp.leftMargin = insets.left; @@ -116,10 +120,15 @@ public class DropTargetBar extends FrameLayout lp.height = grid.dropTargetBarSizePx; lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.TOP; + DeviceProfile dp = mLauncher.getDeviceProfile(); + int horizontalPadding = dp.dropTargetHorizontalPaddingPx; + int verticalPadding = dp.dropTargetVerticalPaddingPx; setLayoutParams(lp); for (ButtonDropTarget button : mDropTargets) { button.setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.dropTargetTextSizePx); button.setToolTipLocation(tooltipLocation); + button.setPadding(horizontalPadding, verticalPadding, horizontalPadding, + verticalPadding); } } @@ -135,36 +144,83 @@ public class DropTargetBar extends FrameLayout protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = MeasureSpec.getSize(widthMeasureSpec); int height = MeasureSpec.getSize(heightMeasureSpec); + int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); - int visibleCount = getVisibleButtonsCount(); - if (visibleCount > 0) { - int availableWidth = width / visibleCount; - boolean textVisible = true; - boolean textResized = false; - float textSize = mDropTargets[0].getTextSize(); - for (ButtonDropTarget button : mDropTargets) { - if (button.getVisibility() == GONE) { - continue; - } - if (button.isTextTruncated(availableWidth)) { - textSize = Math.min(textSize, button.resizeTextToFit(availableWidth)); - textResized = true; - } - textVisible = textVisible && !button.isTextTruncated(availableWidth); - } + int visibleCount = getVisibleButtons(mTempTargets); + if (visibleCount == 1) { + int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); - if (textResized) { - for (ButtonDropTarget button : mDropTargets) { - button.setTextSize(textSize); - } - } + ButtonDropTarget firstButton = mTempTargets[0]; + firstButton.setTextVisible(true); + firstButton.setIconVisible(true); + firstButton.measure(widthSpec, heightSpec); + } else if (visibleCount == 2) { + DeviceProfile dp = mLauncher.getDeviceProfile(); + int verticalPadding = dp.dropTargetVerticalPaddingPx; + int horizontalPadding = dp.dropTargetHorizontalPaddingPx; - int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST); - int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); - for (ButtonDropTarget button : mDropTargets) { - if (button.getVisibility() != GONE) { - button.setTextVisible(textVisible); - button.measure(widthSpec, heightSpec); + ButtonDropTarget firstButton = mTempTargets[0]; + firstButton.setTextVisible(true); + firstButton.setIconVisible(true); + + ButtonDropTarget secondButton = mTempTargets[1]; + secondButton.setTextVisible(true); + secondButton.setIconVisible(true); + secondButton.setTextMultiLine(false); + // Reset second button padding in case it was previously changed to multi-line text. + secondButton.setPadding(horizontalPadding, verticalPadding, horizontalPadding, + verticalPadding); + + if (dp.isTwoPanels) { + // Both buttons for two panel fit to the width of one Cell Layout (less + // half of the center gap between the buttons). + float scale = dp.getWorkspaceSpringLoadScale(); + int scaledPanelWidth = (int) (dp.getCellLayoutWidth() * scale); + int halfButtonGap = dp.dropTargetGapPx / 2; + scaledPanelWidth -= halfButtonGap / 2; + + int widthSpec = MeasureSpec.makeMeasureSpec(scaledPanelWidth, MeasureSpec.AT_MOST); + firstButton.measure(widthSpec, heightSpec); + secondButton.measure(widthSpec, heightSpec); + } else { + int availableWidth; + int buttonGap = dp.dropTargetGapPx; + if (mIsVertical) { + // Both buttons plus the button gap do not display past the edge of the + // scaled workspace, less a pre-defined gap from the edge of the workspace. + float scale = dp.getWorkspaceSpringLoadScale(); + int panelWidth = (int) (dp.getCellLayoutWidth() * scale); + availableWidth = Math.min( + panelWidth - (2 * dp.dropTargetButtonWorkspaceEdgeGapPx), width); + } else { + // Both buttons plus the button gap display up to a pre-defined margin of + // the unscaled workspace edge. + availableWidth = Math.min( + dp.availableWidthPx - (2 * dp.dropTargetButtonScreenEdgeGapPx), + width); + } + int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth - buttonGap, + MeasureSpec.AT_MOST); + + // First button's width is at most the drop target bar's total width less the button + // gap. + firstButton.measure(widthSpec, heightSpec); + + int usedWidth = firstButton.getMeasuredWidth() + buttonGap; + int remainingWidth = availableWidth - usedWidth; + widthSpec = MeasureSpec.makeMeasureSpec(remainingWidth, MeasureSpec.AT_MOST); + secondButton.measure(widthSpec, heightSpec); + + // Remove both icons and put the second button's text on two lines if text is + // truncated on phones. We assume first button's text is never truncated, so it + // remains single-line. + if (secondButton.isTextTruncated(remainingWidth) && !mIsVertical) { + firstButton.setIconVisible(false); + secondButton.setIconVisible(false); + secondButton.setTextMultiLine(true); + secondButton.setPadding(secondButton.getPaddingLeft(), + secondButton.getPaddingTop() / 2, secondButton.getPaddingRight(), + secondButton.getPaddingBottom() / 2); } } } @@ -173,98 +229,79 @@ public class DropTargetBar extends FrameLayout @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - int visibleCount = getVisibleButtonsCount(); + int visibleCount = getVisibleButtons(mTempTargets); if (visibleCount == 0) { return; } - Launcher launcher = Launcher.getLauncher(getContext()); - Workspace workspace = launcher.getWorkspace(); - DeviceProfile dp = launcher.getDeviceProfile(); - int buttonHorizontalPadding = dp.dropTargetHorizontalPaddingPx; - int buttonVerticalPadding = dp.dropTargetVerticalPaddingPx; + DeviceProfile dp = mLauncher.getDeviceProfile(); int barCenter = (right - left) / 2; - - ButtonDropTarget[] visibleButtons = Arrays.stream(mDropTargets) - .filter(b -> b.getVisibility() != GONE) - .toArray(ButtonDropTarget[]::new); - Arrays.stream(visibleButtons).forEach( - b -> b.setPadding(buttonHorizontalPadding, buttonVerticalPadding, - buttonHorizontalPadding, buttonVerticalPadding)); + if (mIsVertical) { + // Center vertical bar over scaled workspace, accounting for hotseat offset. + float scale = dp.getWorkspaceSpringLoadScale(); + Workspace ws = mLauncher.getWorkspace(); + int workspaceCenter = (ws.getLeft() + ws.getRight()) / 2; + int cellLayoutCenter = ((dp.getInsets().left + dp.workspacePadding.left) + (dp.widthPx + - dp.getInsets().right - dp.workspacePadding.right)) / 2; + int cellLayoutCenterOffset = (int) ((cellLayoutCenter - workspaceCenter) * scale); + barCenter = workspaceCenter + cellLayoutCenterOffset; + } if (visibleCount == 1) { - ButtonDropTarget button = visibleButtons[0]; + ButtonDropTarget button = mTempTargets[0]; button.layout(barCenter - (button.getMeasuredWidth() / 2), 0, barCenter + (button.getMeasuredWidth() / 2), button.getMeasuredHeight()); } else if (visibleCount == 2) { int buttonGap = dp.dropTargetGapPx; if (dp.isTwoPanels) { - ButtonDropTarget leftButton = visibleButtons[0]; + ButtonDropTarget leftButton = mTempTargets[0]; leftButton.layout(barCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), 0, barCenter - (buttonGap / 2), leftButton.getMeasuredHeight()); - ButtonDropTarget rightButton = visibleButtons[1]; + ButtonDropTarget rightButton = mTempTargets[1]; rightButton.layout(barCenter + (buttonGap / 2), 0, - barCenter + rightButton.getMeasuredWidth() + (buttonGap / 2), + barCenter + (buttonGap / 2) + rightButton.getMeasuredWidth(), rightButton.getMeasuredHeight()); - } else if (dp.isTablet) { - int numberOfMargins = visibleCount - 1; - int buttonWidths = Arrays.stream(mDropTargets) - .filter(b -> b.getVisibility() != GONE) - .mapToInt(ButtonDropTarget::getMeasuredWidth) - .sum(); - int totalWidth = buttonWidths + (numberOfMargins * buttonGap); - int buttonsStartMargin = barCenter - (totalWidth / 2); - - int start = buttonsStartMargin; - for (ButtonDropTarget button : visibleButtons) { - int margin = (start != buttonsStartMargin) ? buttonGap : 0; - button.layout(start + margin, 0, start + margin + button.getMeasuredWidth(), - button.getMeasuredHeight()); - start += button.getMeasuredWidth() + margin; - } - } else if (mIsVertical) { - // Center buttons over workspace, not screen. - int verticalCenter = (workspace.getRight() - workspace.getLeft()) / 2; - ButtonDropTarget leftButton = visibleButtons[0]; - leftButton.layout(verticalCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), - 0, verticalCenter - (buttonGap / 2), leftButton.getMeasuredHeight()); - - ButtonDropTarget rightButton = visibleButtons[1]; - rightButton.layout(verticalCenter + (buttonGap / 2), 0, - verticalCenter + rightButton.getMeasuredWidth() + (buttonGap / 2), - rightButton.getMeasuredHeight()); - } else if (dp.isPhone) { - // Buttons aligned to outer edges of scaled workspace. - float scale = dp.getWorkspaceSpringLoadScale(); - - int workspaceWidth = (int) (launcher.getWorkspace().getNormalChildWidth() * scale); - int start = barCenter - (workspaceWidth / 2); - int end = barCenter + (workspaceWidth / 2); - - ButtonDropTarget leftButton = visibleButtons[0]; - ButtonDropTarget rightButton = visibleButtons[1]; - - // If the text within the buttons is too long, the buttons can overlap - int overlap = start + leftButton.getMeasuredWidth() + rightButton.getMeasuredWidth() - - end; - if (overlap > 0) { - end += overlap; + } else { + int start; + int end; + if (mIsVertical) { + // Scaled CellLayout width is assumed to not exceed the bounds of left/right. + float scale = dp.getWorkspaceSpringLoadScale(); + int panelWidth = (int) (dp.getCellLayoutWidth() * scale); + start = barCenter - (panelWidth / 2) + dp.dropTargetButtonWorkspaceEdgeGapPx; + end = barCenter + (panelWidth / 2) - dp.dropTargetButtonWorkspaceEdgeGapPx; + } else { + start = Math.max(dp.dropTargetButtonScreenEdgeGapPx, left); + end = Math.min(dp.availableWidthPx - dp.dropTargetButtonScreenEdgeGapPx, right); } - leftButton.layout(start, 0, start + leftButton.getMeasuredWidth(), + ButtonDropTarget leftButton = mTempTargets[0]; + ButtonDropTarget rightButton = mTempTargets[1]; + + int leftButtonWidth = leftButton.getMeasuredWidth(); + int rightButtonWidth = rightButton.getMeasuredWidth(); + int buttonPlusGapWidth = leftButtonWidth + buttonGap + rightButtonWidth; + + int extraSpace = end - start - buttonPlusGapWidth; + start = (start - left) + (extraSpace / 2); + + leftButton.layout(start, 0, start + leftButtonWidth, leftButton.getMeasuredHeight()); - rightButton.layout(end - rightButton.getMeasuredWidth(), 0, end, + + int rightButtonStart = start + leftButtonWidth + buttonGap; + rightButton.layout(rightButtonStart, 0, rightButtonStart + rightButtonWidth, rightButton.getMeasuredHeight()); } } } - private int getVisibleButtonsCount() { + private int getVisibleButtons(ButtonDropTarget[] outVisibleButtons) { int visibleCount = 0; - for (ButtonDropTarget buttons : mDropTargets) { - if (buttons.getVisibility() != GONE) { + for (ButtonDropTarget button : mDropTargets) { + if (button.getVisibility() != GONE) { + outVisibleButtons[visibleCount] = button; visibleCount++; } }