diff --git a/res/values-sw720dp/dimens.xml b/res/values-sw720dp/dimens.xml index 7b2ed8bc65..c16792a2e4 100644 --- a/res/values-sw720dp/dimens.xml +++ b/res/values-sw720dp/dimens.xml @@ -31,7 +31,6 @@ 24dp 20dp 32dp - 32dp 110dp 48dp diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 2612a7d13e..99346f3ba5 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -24,8 +24,6 @@ 7dp 8dp - - 24dp 16dp 10.77dp @@ -60,10 +58,9 @@ 56dp 20dp - 32dp + 36dp 16dp - 10sp 1sp @@ -240,9 +237,7 @@ 8dp 16dp 8dp - 28dp - 0dp - 28dp + 22dp 30dp diff --git a/src/com/android/launcher3/ButtonDropTarget.java b/src/com/android/launcher3/ButtonDropTarget.java index 8da4f053df..0b07c952bb 100644 --- a/src/com/android/launcher3/ButtonDropTarget.java +++ b/src/com/android/launcher3/ButtonDropTarget.java @@ -24,7 +24,6 @@ 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; @@ -50,8 +49,6 @@ 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; @@ -75,8 +72,6 @@ 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; @@ -114,7 +109,8 @@ public abstract class ButtonDropTarget extends TextView // drawableLeft and drawableStart. mDrawable = getContext().getDrawable(resId).mutate(); mDrawable.setTintList(getTextColors()); - updateIconVisibility(); + centerIcon(); + setCompoundDrawablesRelative(mDrawable, null, null, null); } public void setDropTargetBar(DropTargetBar dropTargetBar) { @@ -310,47 +306,11 @@ public abstract class ButtonDropTarget extends TextView if (mTextVisible != isVisible || !TextUtils.equals(newText, getText())) { mTextVisible = isVisible; setText(newText); - 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(mDrawable, null, null, null); + int drawablePadding = mTextVisible ? mDrawablePadding : 0; + setCompoundDrawablePadding(drawablePadding); } - setCompoundDrawablesRelative(mIconVisible ? mDrawable : null, null, null, null); - setCompoundDrawablePadding(mIconVisible && mTextVisible ? mDrawablePadding : 0); } @Override @@ -364,6 +324,40 @@ 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 515221752a..4bb6f7894c 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -108,7 +108,6 @@ public class DeviceProfile { public float workspaceSpringLoadShrunkTop; public float workspaceSpringLoadShrunkBottom; public final int workspaceSpringLoadedBottomSpace; - public final int workspaceSpringLoadedMinNextPageVisiblePx; private final int extraSpace; public int workspaceTopPadding; @@ -215,8 +214,6 @@ 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(); @@ -344,15 +341,9 @@ 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); @@ -508,7 +499,7 @@ public class DeviceProfile { */ private int calculateQsbWidth() { if (isQsbInline) { - int columns = getPanelCount() * inv.numColumns; + int columns = isTwoPanels ? inv.numColumns * 2 : inv.numColumns; return getIconToIconWidthForColumns(columns) - iconSizePx * numShownHotseatIcons - hotseatBorderSpace * numShownHotseatIcons; @@ -960,6 +951,13 @@ 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. */ @@ -971,7 +969,8 @@ 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 * workspaceSpringLoadedMinNextPageVisiblePx); + float maxAvailableWidth = + workspaceWidth - (2 * getWorkspaceSpringLoadedMinimumNextPageVisible()); if (scaledWorkspaceWidth > maxAvailableWidth) { scale *= maxAvailableWidth / scaledWorkspaceWidth; } @@ -1410,19 +1409,11 @@ 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 37cb4a1e74..2e3f26c7d0 100644 --- a/src/com/android/launcher3/DropTargetBar.java +++ b/src/com/android/launcher3/DropTargetBar.java @@ -39,6 +39,8 @@ 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. */ @@ -51,8 +53,6 @@ public class DropTargetBar extends FrameLayout private final Runnable mFadeAnimationEndRunnable = () -> updateVisibility(DropTargetBar.this); - private final Launcher mLauncher; - @ViewDebug.ExportedProperty(category = "launcher") protected boolean mDeferOnDragEnd; @@ -60,19 +60,16 @@ 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 @@ -83,13 +80,12 @@ 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 = mLauncher.getDeviceProfile(); + DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile(); mIsVertical = grid.isVerticalBarLayout(); lp.leftMargin = insets.left; @@ -120,15 +116,10 @@ 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); } } @@ -144,83 +135,36 @@ 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 = getVisibleButtons(mTempTargets); - if (visibleCount == 1) { - int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST); - - 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; - - 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 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; } - int widthSpec = MeasureSpec.makeMeasureSpec(availableWidth - buttonGap, - MeasureSpec.AT_MOST); + if (button.isTextTruncated(availableWidth)) { + textSize = Math.min(textSize, button.resizeTextToFit(availableWidth)); + textResized = true; + } + textVisible = textVisible && !button.isTextTruncated(availableWidth); + } - // First button's width is at most the drop target bar's total width less the button - // gap. - firstButton.measure(widthSpec, heightSpec); + if (textResized) { + for (ButtonDropTarget button : mDropTargets) { + button.setTextSize(textSize); + } + } - 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); + 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); } } } @@ -229,87 +173,98 @@ public class DropTargetBar extends FrameLayout @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - int visibleCount = getVisibleButtons(mTempTargets); + int visibleCount = getVisibleButtonsCount(); if (visibleCount == 0) { return; } - DeviceProfile dp = mLauncher.getDeviceProfile(); + Launcher launcher = Launcher.getLauncher(getContext()); + Workspace workspace = launcher.getWorkspace(); + DeviceProfile dp = launcher.getDeviceProfile(); + int buttonHorizontalPadding = dp.dropTargetHorizontalPaddingPx; + int buttonVerticalPadding = dp.dropTargetVerticalPaddingPx; int barCenter = (right - left) / 2; - 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; - } + + 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 (visibleCount == 1) { - ButtonDropTarget button = mTempTargets[0]; + ButtonDropTarget button = visibleButtons[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 = mTempTargets[0]; + ButtonDropTarget leftButton = visibleButtons[0]; leftButton.layout(barCenter - leftButton.getMeasuredWidth() - (buttonGap / 2), 0, barCenter - (buttonGap / 2), leftButton.getMeasuredHeight()); - ButtonDropTarget rightButton = mTempTargets[1]; + ButtonDropTarget rightButton = visibleButtons[1]; rightButton.layout(barCenter + (buttonGap / 2), 0, - barCenter + (buttonGap / 2) + rightButton.getMeasuredWidth(), + barCenter + rightButton.getMeasuredWidth() + (buttonGap / 2), rightButton.getMeasuredHeight()); - } 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); + } 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; } - 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; - int leftBound = Math.max(left, 0); - int rightBound = Math.min(right, dp.availableWidthPx); - - int leftButtonStart = Utilities.boundToRange( - (start - left) + (extraSpace / 2), leftBound, rightBound); - int leftButtonEnd = Utilities.boundToRange( - leftButtonStart + leftButtonWidth, leftBound, rightBound); - int rightButtonStart = Utilities.boundToRange( - leftButtonEnd + buttonGap, leftBound, rightBound); - int rightButtonEnd = Utilities.boundToRange( - rightButtonStart + rightButtonWidth, leftBound, rightBound); - - leftButton.layout(leftButtonStart, 0, leftButtonEnd, + leftButton.layout(start, 0, start + leftButton.getMeasuredWidth(), leftButton.getMeasuredHeight()); - rightButton.layout(rightButtonStart, 0, rightButtonEnd, + rightButton.layout(end - rightButton.getMeasuredWidth(), 0, end, rightButton.getMeasuredHeight()); } } } - private int getVisibleButtons(ButtonDropTarget[] outVisibleButtons) { + private int getVisibleButtonsCount() { int visibleCount = 0; - for (ButtonDropTarget button : mDropTargets) { - if (button.getVisibility() != GONE) { - outVisibleButtons[visibleCount] = button; + for (ButtonDropTarget buttons : mDropTargets) { + if (buttons.getVisibility() != GONE) { visibleCount++; } }