Merge "Using same layout for drop-target bar in landscape and portrait" into ub-launcher3-master

This commit is contained in:
Sunny Goyal 2018-01-19 20:39:46 +00:00 committed by Android (Google) Code Review
commit d8a3f3c251
12 changed files with 271 additions and 262 deletions

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="?android:attr/colorBackground" />
<corners android:radius="2dp" />
</shape>

View File

@ -67,7 +67,7 @@
<include
android:id="@+id/drop_target_bar"
layout="@layout/drop_target_bar_vert" />
layout="@layout/drop_target_bar" />
<include layout="@layout/all_apps"
android:id="@+id/apps_view"

View File

@ -66,7 +66,7 @@
<include
android:id="@+id/drop_target_bar"
layout="@layout/drop_target_bar_horz" />
layout="@layout/drop_target_bar" />
<include layout="@layout/all_apps"
android:id="@+id/apps_view"

View File

@ -60,7 +60,7 @@
<include
android:id="@+id/drop_target_bar"
layout="@layout/drop_target_bar_horz" />
layout="@layout/drop_target_bar" />
<!-- Keep these behind the workspace so that they are not visible when
we go into AllApps -->

View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher3.DropTargetBar xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_drop_target_size"
android:layout_gravity="center_horizontal|top"
android:focusable="false"
android:alpha="0"
android:theme="@style/HomeScreenElementTheme"
android:visibility="invisible">
<!-- Delete target -->
<com.android.launcher3.DeleteDropTarget
android:id="@+id/delete_target_text"
style="@style/DropTargetButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/remove_drop_target_label" />
<!-- App Info -->
<com.android.launcher3.InfoDropTarget
android:id="@+id/info_target_text"
style="@style/DropTargetButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/app_info_drop_target_label" />
<!-- Uninstall target -->
<com.android.launcher3.UninstallDropTarget
android:id="@+id/uninstall_target_text"
style="@style/DropTargetButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:text="@string/uninstall_drop_target_label" />
</com.android.launcher3.DropTargetBar>

View File

@ -1,81 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher3.DropTargetBar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
android:theme="@style/HomeScreenElementTheme"
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_drop_target_size"
android:visibility="invisible"
android:layout_gravity="center_horizontal|top"
android:focusable="false">
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<!-- Delete target -->
<com.android.launcher3.DeleteDropTarget
launcher:hideParentOnDisable="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/delete_target_text"
style="@style/DropTargetButton"
android:text="@string/remove_drop_target_label" />
</FrameLayout>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<!-- App Info -->
<com.android.launcher3.InfoDropTarget
launcher:hideParentOnDisable="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/info_target_text"
style="@style/DropTargetButton"
android:text="@string/app_info_drop_target_label" />
</FrameLayout>
<FrameLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<!-- Uninstall target -->
<com.android.launcher3.UninstallDropTarget
launcher:hideParentOnDisable="true"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:id="@+id/uninstall_target_text"
style="@style/DropTargetButton"
android:text="@string/uninstall_drop_target_label" />
</FrameLayout>
</com.android.launcher3.DropTargetBar>

View File

@ -1,62 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2016 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<com.android.launcher3.DropTargetBar
android:theme="@style/HomeScreenElementTheme"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dynamic_grid_drop_target_size"
android:orientation="vertical"
android:layout_height="match_parent"
android:layout_gravity="left"
android:visibility="invisible"
android:focusable="false"
android:paddingTop="@dimen/vert_drop_target_vertical_gap" >
<!-- Delete target -->
<com.android.launcher3.DeleteDropTarget
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_drop_target_size"
android:gravity="center"
android:paddingLeft="@dimen/vert_drop_target_horizontal_gap"
android:paddingRight="@dimen/vert_drop_target_horizontal_gap"
android:id="@+id/delete_target_text" />
<!-- Uninstall target -->
<com.android.launcher3.UninstallDropTarget
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_drop_target_size"
android:gravity="center"
android:paddingLeft="@dimen/vert_drop_target_horizontal_gap"
android:paddingRight="@dimen/vert_drop_target_horizontal_gap"
android:id="@+id/uninstall_target_text"
android:layout_marginTop="@dimen/vert_drop_target_vertical_gap"/>
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<!-- App Info -->
<com.android.launcher3.InfoDropTarget
android:layout_width="match_parent"
android:layout_height="@dimen/dynamic_grid_drop_target_size"
android:gravity="center"
android:paddingLeft="@dimen/vert_drop_target_horizontal_gap"
android:paddingRight="@dimen/vert_drop_target_horizontal_gap"
android:id="@+id/info_target_text"
android:layout_marginBottom="64dp"/>
</com.android.launcher3.DropTargetBar>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2018 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/tooltip_frame"
android:ellipsize="end"
android:maxLines="1"
android:maxWidth="256dp"
android:paddingBottom="6.5dp"
android:paddingEnd="16dp"
android:paddingStart="16dp"
android:paddingTop="6.5dp"
android:textSize="14sp"
android:fontFamily="sans-serif"
android:textColor="?android:attr/colorForeground" />

View File

@ -91,10 +91,6 @@
<attr name="layout_ignoreInsets" format="boolean" />
</declare-styleable>
<declare-styleable name="ButtonDropTarget">
<attr name="hideParentOnDisable" format="boolean" />
</declare-styleable>
<declare-styleable name="InvariantDeviceProfile">
<attr name="name" format="string" />
<attr name="minWidthDps" format="float" />

View File

@ -49,8 +49,7 @@
<!-- Drop target bar -->
<dimen name="dynamic_grid_drop_target_size">48dp</dimen>
<dimen name="vert_drop_target_vertical_gap">20dp</dimen>
<dimen name="vert_drop_target_horizontal_gap">14dp</dimen>
<dimen name="drop_target_vertical_gap">20dp</dimen>
<!-- App Widget resize frame -->
<dimen name="widget_handle_margin">13dp</dimen>

View File

@ -16,27 +16,28 @@
package com.android.launcher3;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static com.android.launcher3.LauncherState.NORMAL;
import android.animation.AnimatorSet;
import android.animation.FloatArrayEvaluator;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.widget.PopupWindow;
import android.widget.TextView;
import com.android.launcher3.anim.Interpolators;
@ -56,7 +57,10 @@ public abstract class ButtonDropTarget extends TextView
private static final int[] sTempCords = new int[2];
private static final int DRAG_VIEW_DROP_DURATION = 285;
private final boolean mHideParentOnDisable;
public static final int TOOLTIP_DEFAULT = 0;
public static final int TOOLTIP_LEFT = 1;
public static final int TOOLTIP_RIGHT = 2;
protected final Launcher mLauncher;
private int mBottomDragPadding;
@ -75,6 +79,10 @@ public abstract class ButtonDropTarget extends TextView
protected CharSequence mText;
protected ColorStateList mOriginalTextColor;
protected Drawable mDrawable;
private boolean mTextVisible = true;
private PopupWindow mToolTip;
private int mToolTipLocation;
private AnimatorSet mCurrentColorAnim;
@Thunk ColorMatrix mSrcFilter, mDstFilter, mCurrentFilter;
@ -89,11 +97,6 @@ public abstract class ButtonDropTarget extends TextView
Resources resources = getResources();
mBottomDragPadding = resources.getDimensionPixelSize(R.dimen.drop_target_drag_padding);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ButtonDropTarget, defStyle, 0);
mHideParentOnDisable = a.getBoolean(R.styleable.ButtonDropTarget_hideParentOnDisable, false);
a.recycle();
mDragDistanceThreshold = resources.getDimensionPixelSize(R.dimen.drag_distanceThreshold);
}
@ -102,21 +105,56 @@ public abstract class ButtonDropTarget extends TextView
super.onFinishInflate();
mText = getText();
mOriginalTextColor = getTextColors();
setContentDescription(mText);
}
protected void setDrawable(int resId) {
// We do not set the drawable in the xml as that inflates two drawables corresponding to
// drawableLeft and drawableStart.
setCompoundDrawablesRelativeWithIntrinsicBounds(resId, 0, 0, 0);
mDrawable = getCompoundDrawablesRelative()[0];
if (mTextVisible) {
setCompoundDrawablesRelativeWithIntrinsicBounds(resId, 0, 0, 0);
mDrawable = getCompoundDrawablesRelative()[0];
} else {
setCompoundDrawablesRelativeWithIntrinsicBounds(0, resId, 0, 0);
mDrawable = getCompoundDrawablesRelative()[1];
}
}
public void setDropTargetBar(DropTargetBar dropTargetBar) {
mDropTargetBar = dropTargetBar;
}
private void hideTooltip() {
if (mToolTip != null) {
mToolTip.dismiss();
mToolTip = null;
}
}
@Override
public final void onDragEnter(DragObject d) {
if (!d.accessibleDrag && !mTextVisible) {
// Show tooltip
hideTooltip();
TextView message = (TextView) LayoutInflater.from(getContext()).inflate(
R.layout.drop_target_tool_tip, null);
message.setText(mText);
mToolTip = new PopupWindow(message, WRAP_CONTENT, WRAP_CONTENT);
int x = 0, y = 0;
if (mToolTipLocation != TOOLTIP_DEFAULT) {
y = -getMeasuredHeight();
message.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if (mToolTipLocation == TOOLTIP_LEFT) {
x = - getMeasuredWidth() - message.getMeasuredWidth() / 2;
} else {
x = getMeasuredWidth() / 2 + message.getMeasuredWidth() / 2;
}
}
mToolTip.showAsDropDown(this, x, y);
}
d.dragView.setColor(mHoverColor);
animateTextColor(mHoverColor);
if (d.stateAnnouncer != null) {
@ -153,13 +191,9 @@ public abstract class ButtonDropTarget extends TextView
ValueAnimator anim1 = ValueAnimator.ofObject(
new FloatArrayEvaluator(mCurrentFilter.getArray()),
mSrcFilter.getArray(), mDstFilter.getArray());
anim1.addUpdateListener(new AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
invalidate();
}
anim1.addUpdateListener((anim) -> {
mDrawable.setColorFilter(new ColorMatrixColorFilter(mCurrentFilter));
invalidate();
});
mCurrentColorAnim.play(anim1);
@ -169,6 +203,8 @@ public abstract class ButtonDropTarget extends TextView
@Override
public final void onDragExit(DragObject d) {
hideTooltip();
if (!d.dragComplete) {
d.dragView.setColor(0);
resetHoverColor();
@ -187,8 +223,7 @@ public abstract class ButtonDropTarget extends TextView
mCurrentColorAnim = null;
}
setTextColor(mOriginalTextColor);
(mHideParentOnDisable ? ((ViewGroup) getParent()) : this)
.setVisibility(mActive ? View.VISIBLE : View.GONE);
setVisibility(mActive ? View.VISIBLE : View.GONE);
mAccessibleDrag = options.isAccessibleDrag;
setOnClickListener(mAccessibleDrag ? this : null);
@ -230,14 +265,12 @@ public abstract class ButtonDropTarget extends TextView
final float scale = (float) to.width() / from.width();
mDropTargetBar.deferOnDragEnd();
Runnable onAnimationEndRunnable = new Runnable() {
@Override
public void run() {
completeDrop(d);
mDropTargetBar.onDragEnd();
mLauncher.getStateManager().goToState(NORMAL);
}
Runnable onAnimationEndRunnable = () -> {
completeDrop(d);
mDropTargetBar.onDragEnd();
mLauncher.getStateManager().goToState(NORMAL);
};
dragLayer.animateView(d.dragView, from, to, scale, 1f, 1f, 0.1f, 0.1f,
DRAG_VIEW_DROP_DURATION,
Interpolators.DEACCEL_2, Interpolators.LINEAR, onAnimationEndRunnable,
@ -294,8 +327,8 @@ public abstract class ButtonDropTarget extends TextView
to.set(left, top, right, bottom);
// Center the destination rect about the trash icon
final int xOffset = (int) -(viewWidth - width) / 2;
final int yOffset = (int) -(viewHeight - height) / 2;
final int xOffset = -(viewWidth - width) / 2;
final int yOffset = -(viewHeight - height) / 2;
to.offset(xOffset, yOffset);
return to;
@ -310,25 +343,24 @@ public abstract class ButtonDropTarget extends TextView
return getTextColors().getDefaultColor();
}
/**
* Returns True if any update was made.
*/
public boolean updateText(boolean hide) {
if ((hide && getText().toString().isEmpty()) || (!hide && mText.equals(getText()))) {
return false;
public void setTextVisible(boolean isVisible) {
if (mTextVisible != isVisible) {
mTextVisible = isVisible;
setText(isVisible ? mText : "");
if (mTextVisible) {
setCompoundDrawablesRelativeWithIntrinsicBounds(mDrawable, null, null, null);
} else {
setCompoundDrawablesRelativeWithIntrinsicBounds(null, mDrawable, null, null);
}
}
setText(hide ? "" : mText);
return true;
}
public boolean isTextTruncated() {
int availableWidth = getMeasuredWidth();
if (mHideParentOnDisable) {
ViewGroup parent = (ViewGroup) getParent();
availableWidth = parent.getMeasuredWidth() - parent.getPaddingLeft()
- parent.getPaddingRight();
}
public void setToolTipLocation(int location) {
mToolTipLocation = location;
hideTooltip();
}
public boolean isTextTruncated(int availableWidth) {
availableWidth -= (getPaddingLeft() + getPaddingRight() + mDrawable.getIntrinsicWidth()
+ getCompoundDrawablePadding());
CharSequence displayedText = TextUtils.ellipsize(mText, getPaint(), availableWidth,

View File

@ -17,6 +17,9 @@
package com.android.launcher3;
import static com.android.launcher3.AlphaUpdateListener.updateVisibility;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_DEFAULT;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_LEFT;
import static com.android.launcher3.ButtonDropTarget.TOOLTIP_RIGHT;
import static com.android.launcher3.compat.AccessibilityManagerCompat.isAccessibilityEnabled;
import android.animation.TimeInterpolator;
@ -26,22 +29,18 @@ import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragController.DragListener;
import com.android.launcher3.dragndrop.DragOptions;
import java.util.ArrayList;
/*
* The top bar containing various drop targets: Delete/App Info/Uninstall.
*/
public class DropTargetBar extends LinearLayout
public class DropTargetBar extends FrameLayout
implements DragListener, Insettable {
protected static final int DEFAULT_DRAG_FADE_DURATION = 175;
@ -59,6 +58,8 @@ public class DropTargetBar extends LinearLayout
private ButtonDropTarget[] mDropTargets;
private ViewPropertyAnimator mCurrentAnimation;
private boolean mIsVertical = true;
public DropTargetBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
@ -70,25 +71,30 @@ public class DropTargetBar extends LinearLayout
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// Initialize with hidden state
setAlpha(0f);
mDropTargets = new ButtonDropTarget[getChildCount()];
for (int i = 0; i < mDropTargets.length; i++) {
mDropTargets[i] = (ButtonDropTarget) getChildAt(i);
mDropTargets[i].setDropTargetBar(this);
}
}
@Override
public void setInsets(Rect insets) {
FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
DeviceProfile grid = Launcher.getLauncher(getContext()).getDeviceProfile();
mIsVertical = grid.isVerticalBarLayout();
lp.leftMargin = insets.left;
lp.topMargin = insets.top;
lp.bottomMargin = insets.bottom;
lp.rightMargin = insets.right;
int tooltipLocation = TOOLTIP_DEFAULT;
if (grid.isVerticalBarLayout()) {
lp.width = grid.dropTargetBarSizePx;
lp.height = grid.availableHeightPx - 2 * grid.edgeMarginPx;
lp.gravity = insets.left > insets.right ? Gravity.RIGHT : Gravity.LEFT;
tooltipLocation = insets.left > insets.right ? TOOLTIP_LEFT : TOOLTIP_RIGHT;
} else {
int gap;
if (grid.isTablet) {
@ -107,83 +113,95 @@ public class DropTargetBar extends LinearLayout
lp.height = grid.dropTargetBarSizePx;
}
setLayoutParams(lp);
for (ButtonDropTarget button : mDropTargets) {
button.setToolTipLocation(tooltipLocation);
}
}
public void setup(DragController dragController) {
dragController.addDragListener(this);
ArrayList<ButtonDropTarget> outList = new ArrayList<>();
findDropTargets(this, outList);
mDropTargets = new ButtonDropTarget[outList.size()];
for (int i = 0; i < mDropTargets.length; i++) {
mDropTargets[i] = outList.get(i);
mDropTargets[i].setDropTargetBar(this);
dragController.addDragListener(mDropTargets[i]);
dragController.addDropTarget(mDropTargets[i]);
}
}
private static void findDropTargets(View view, ArrayList<ButtonDropTarget> outTargets) {
if (view instanceof ButtonDropTarget) {
outTargets.add((ButtonDropTarget) view);
} else if (view instanceof ViewGroup) {
ViewGroup vg = (ViewGroup) view;
for (int i = vg.getChildCount() - 1; i >= 0; i--) {
findDropTargets(vg.getChildAt(i), outTargets);
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
boolean hideText = hideTextHelper(false /* shouldUpdateText */, false /* no-op */);
if (hideTextHelper(true /* shouldUpdateText */, hideText)) {
// Text has changed, so we need to re-measure.
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
if (mIsVertical) {
int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
/**
* Helper method that iterates through the children and returns whether any of the visible
* {@link ButtonDropTarget} has truncated text.
*
* @param shouldUpdateText If True, updates the text of all children.
* @param hideText If True and {@param shouldUpdateText} is True, clears the text of all
* children; otherwise it sets the original text value.
*
*
* @return If shouldUpdateText is True, returns whether any of the children updated their text.
* Else, returns whether any of the children have truncated their text.
*/
private boolean hideTextHelper(boolean shouldUpdateText, boolean hideText) {
boolean result = false;
View visibleView;
ButtonDropTarget dropTarget;
for (int i = getChildCount() - 1; i >= 0; --i) {
if (getChildAt(i) instanceof ButtonDropTarget) {
visibleView = dropTarget = (ButtonDropTarget) getChildAt(i);
} else if (getChildAt(i) instanceof ViewGroup) {
// The Drop Target is wrapped in a FrameLayout.
visibleView = getChildAt(i);
dropTarget = (ButtonDropTarget) ((ViewGroup) visibleView).getChildAt(0);
} else {
// Ignore other views.
continue;
for (ButtonDropTarget button : mDropTargets) {
if (button.getVisibility() != GONE) {
button.setTextVisible(false);
button.measure(widthSpec, heightSpec);
}
}
} else {
int visibleCount = getVisibleButtonsCount();
int availableWidth = width / visibleCount;
boolean textVisible = true;
for (ButtonDropTarget buttons : mDropTargets) {
if (buttons.getVisibility() != GONE) {
textVisible = textVisible && !buttons.isTextTruncated(availableWidth);
}
}
if (visibleView.getVisibility() == View.VISIBLE) {
if (shouldUpdateText) {
result |= dropTarget.updateText(hideText);
} else if (dropTarget.isTextTruncated()) {
result = true;
break;
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);
}
}
}
setMeasuredDimension(width, height);
}
return result;
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
if (mIsVertical) {
int gap = getResources().getDimensionPixelSize(R.dimen.drop_target_vertical_gap);
int start = gap;
int end;
for (ButtonDropTarget button : mDropTargets) {
if (button.getVisibility() != GONE) {
end = start + button.getMeasuredHeight();
button.layout(0, start, button.getMeasuredWidth(), end);
start = end + gap;
}
}
} else {
int visibleCount = getVisibleButtonsCount();
int frameSize = (right - left) / visibleCount;
int start = frameSize / 2;
int halfWidth;
for (ButtonDropTarget button : mDropTargets) {
if (button.getVisibility() != GONE) {
halfWidth = button.getMeasuredWidth() / 2;
button.layout(start - halfWidth, 0,
start + halfWidth, button.getMeasuredHeight());
start = start + frameSize;
}
}
}
}
private int getVisibleButtonsCount() {
int visibleCount = 0;
for (ButtonDropTarget buttons : mDropTargets) {
if (buttons.getVisibility() != GONE) {
visibleCount++;
}
}
return visibleCount;
}
private void animateToVisibility(boolean isVisible) {