summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Dialer <noreply@google.com>2017-12-07 10:57:50 -0800
committerCopybara-Service <copybara-piper@google.com>2017-12-07 18:32:32 -0800
commit25f45be4e54aa5aec3f20fae3bab9e5f803079ca (patch)
tree1d6ebc5792ea0816aebbb05372362d8f151dae63
parent17edc22de11f772a1efe91a9c6b7b4fd7e5d3416 (diff)
Bug: 68953167
Test: Bubble.show PiperOrigin-RevId: 178265418 Change-Id: Iad3b85b10aae736953a64824bac1631d506892c8
-rw-r--r--java/com/android/bubble/Bubble.java144
-rw-r--r--java/com/android/bubble/res/layout/bubble_base.xml67
2 files changed, 166 insertions, 45 deletions
diff --git a/java/com/android/bubble/Bubble.java b/java/com/android/bubble/Bubble.java
index 392daaf28..a25316f5b 100644
--- a/java/com/android/bubble/Bubble.java
+++ b/java/com/android/bubble/Bubble.java
@@ -64,6 +64,7 @@ import android.widget.ViewAnimator;
import com.android.bubble.BubbleInfo.Action;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
import java.util.List;
/**
@@ -96,7 +97,7 @@ public class Bubble {
private BubbleInfo currentInfo;
@Visibility private int visibility;
- private boolean expanded;
+ @VisibleForTesting boolean expanded;
private boolean textShowing;
private boolean hideAfterText;
private CharSequence textAfterShow;
@@ -104,7 +105,7 @@ public class Bubble {
@VisibleForTesting ViewHolder viewHolder;
private ViewPropertyAnimator collapseAnimation;
- private Integer overrideGravity;
+ @VisibleForTesting Integer overrideGravity;
private ViewPropertyAnimator exitAnimator;
private final Runnable collapseRunnable =
@@ -497,13 +498,6 @@ public class Bubble {
ViewGroup.LayoutParams layoutParams = primaryContainer.getLayoutParams();
((FrameLayout.LayoutParams) layoutParams).gravity = onRight ? Gravity.RIGHT : Gravity.LEFT;
primaryContainer.setLayoutParams(layoutParams);
-
- viewHolder
- .getExpandedView()
- .setBackgroundResource(
- onRight
- ? R.drawable.bubble_background_pill_rtl
- : R.drawable.bubble_background_pill_ltr);
}
LayoutParams getWindowParams() {
@@ -570,20 +564,23 @@ public class Bubble {
backgroundRipple.getDrawable(0).setTint(primaryTint);
viewHolder.getPrimaryButton().setBackground(backgroundRipple);
- setBackgroundDrawable(viewHolder.getFirstButton(), primaryTint);
- setBackgroundDrawable(viewHolder.getSecondButton(), primaryTint);
- setBackgroundDrawable(viewHolder.getThirdButton(), primaryTint);
+ for (CheckableImageButton button : viewHolder.getActionButtons()) {
+ setBackgroundDrawable(button, primaryTint);
+ }
int numButtons = currentInfo.getActions().size();
- viewHolder.getThirdButton().setVisibility(numButtons < 3 ? View.GONE : View.VISIBLE);
- viewHolder.getSecondButton().setVisibility(numButtons < 2 ? View.GONE : View.VISIBLE);
+ for (CheckableImageButton button : viewHolder.getThirdButtons()) {
+ button.setVisibility(numButtons < 3 ? View.GONE : View.VISIBLE);
+ }
+ for (CheckableImageButton button : viewHolder.getSecondButtons()) {
+ button.setVisibility(numButtons < 2 ? View.GONE : View.VISIBLE);
+ }
viewHolder.getPrimaryIcon().setImageIcon(currentInfo.getPrimaryIcon());
updatePrimaryIconAnimation();
-
- viewHolder
- .getExpandedView()
- .setBackgroundTintList(ColorStateList.valueOf(currentInfo.getPrimaryColor()));
+ for (View expandedView : viewHolder.getExpandedViews()) {
+ expandedView.setBackgroundTintList(ColorStateList.valueOf(currentInfo.getPrimaryColor()));
+ }
updateButtonStates();
}
@@ -613,11 +610,17 @@ public class Bubble {
int numButtons = currentInfo.getActions().size();
if (numButtons >= 1) {
- configureButton(currentInfo.getActions().get(0), viewHolder.getFirstButton());
+ for (CheckableImageButton button : viewHolder.getFirstButtons()) {
+ configureButton(currentInfo.getActions().get(0), button);
+ }
if (numButtons >= 2) {
- configureButton(currentInfo.getActions().get(1), viewHolder.getSecondButton());
+ for (CheckableImageButton button : viewHolder.getSecondButtons()) {
+ configureButton(currentInfo.getActions().get(1), button);
+ }
if (numButtons >= 3) {
- configureButton(currentInfo.getActions().get(2), viewHolder.getThirdButton());
+ for (CheckableImageButton button : viewHolder.getThirdButtons()) {
+ configureButton(currentInfo.getActions().get(2), button);
+ }
}
}
}
@@ -788,10 +791,15 @@ public class Bubble {
private final TextView primaryText;
private final CheckableImageButton firstButton;
+ private final CheckableImageButton firstButtonRtl;
private final CheckableImageButton secondButton;
+ private final CheckableImageButton secondButtonRtl;
private final CheckableImageButton thirdButton;
+ private final CheckableImageButton thirdButtonRtl;
private final View expandedView;
+ private final View expandedViewRtl;
private final View shadowProvider;
+ private final View shadowProviderRtl;
public ViewHolder(Context context) {
// Window root is not in the layout file so that the inflater has a view to inflate into
@@ -799,14 +807,19 @@ public class Bubble {
LayoutInflater inflater = LayoutInflater.from(root.getContext());
View contentView = inflater.inflate(R.layout.bubble_base, root, true);
expandedView = contentView.findViewById(R.id.bubble_expanded_layout);
+ expandedViewRtl = contentView.findViewById(R.id.bubble_expanded_layout_rtl);
primaryButton = contentView.findViewById(R.id.bubble_button_primary);
primaryIcon = contentView.findViewById(R.id.bubble_icon_primary);
primaryText = contentView.findViewById(R.id.bubble_text);
shadowProvider = contentView.findViewById(R.id.bubble_drawer_shadow_provider);
+ shadowProviderRtl = contentView.findViewById(R.id.bubble_drawer_shadow_provider_rtl);
firstButton = contentView.findViewById(R.id.bubble_icon_first);
+ firstButtonRtl = contentView.findViewById(R.id.bubble_icon_first_rtl);
secondButton = contentView.findViewById(R.id.bubble_icon_second);
+ secondButtonRtl = contentView.findViewById(R.id.bubble_icon_second_rtl);
thirdButton = contentView.findViewById(R.id.bubble_icon_third);
+ thirdButtonRtl = contentView.findViewById(R.id.bubble_icon_third_rtl);
root.setOnBackPressedListener(
() -> {
@@ -839,27 +852,34 @@ public class Bubble {
int parentOffset =
((MarginLayoutParams) ((ViewGroup) expandedView.getParent()).getLayoutParams())
.leftMargin;
- if (isDrawingFromRight()) {
- int maxLeft =
- shadowProvider.getRight()
- - context.getResources().getDimensionPixelSize(R.dimen.bubble_size);
- shadowProvider.setLeft(
- Math.min(maxLeft, expandedView.getLeft() + translationX + parentOffset));
- } else {
- int minRight =
- shadowProvider.getLeft()
- + context.getResources().getDimensionPixelSize(R.dimen.bubble_size);
- shadowProvider.setRight(
- Math.max(minRight, expandedView.getRight() + translationX + parentOffset));
- }
+ int minRight =
+ shadowProvider.getLeft()
+ + context.getResources().getDimensionPixelSize(R.dimen.bubble_size);
+ shadowProvider.setRight(
+ Math.max(minRight, expandedView.getRight() + translationX + parentOffset));
+ });
+ expandedViewRtl
+ .getViewTreeObserver()
+ .addOnDrawListener(
+ () -> {
+ int translationX = (int) expandedViewRtl.getTranslationX();
+ int parentOffset =
+ ((MarginLayoutParams)
+ ((ViewGroup) expandedViewRtl.getParent()).getLayoutParams())
+ .leftMargin;
+ int maxLeft =
+ shadowProviderRtl.getRight()
+ - context.getResources().getDimensionPixelSize(R.dimen.bubble_size);
+ shadowProviderRtl.setLeft(
+ Math.min(maxLeft, expandedViewRtl.getLeft() + translationX + parentOffset));
});
moveHandler = new MoveHandler(primaryButton, Bubble.this);
}
private void setChildClickable(boolean clickable) {
- firstButton.setClickable(clickable);
- secondButton.setClickable(clickable);
- thirdButton.setClickable(clickable);
+ for (CheckableImageButton button : getActionButtons()) {
+ button.setClickable(clickable);
+ }
primaryButton.setOnTouchListener(clickable ? moveHandler : null);
}
@@ -880,29 +900,65 @@ public class Bubble {
return primaryText;
}
+ /** Get list of all the action buttons from both LTR/RTL drawers. */
+ public List<CheckableImageButton> getActionButtons() {
+ return Arrays.asList(
+ firstButton, firstButtonRtl, secondButton, secondButtonRtl, thirdButton, thirdButtonRtl);
+ }
+
+ /** Get the first action button used in the current orientation drawer. */
public CheckableImageButton getFirstButton() {
- return firstButton;
+ return isDrawingFromRight() ? firstButtonRtl : firstButton;
+ }
+
+ /** Get both of the first action buttons from both LTR/RTL drawers. */
+ public List<CheckableImageButton> getFirstButtons() {
+ return Arrays.asList(firstButton, firstButtonRtl);
}
+ /** Get the second action button used in the current orientation drawer. */
public CheckableImageButton getSecondButton() {
- return secondButton;
+ return isDrawingFromRight() ? secondButtonRtl : secondButton;
}
+ /** Get both of the second action buttons from both LTR/RTL drawers. */
+ public List<CheckableImageButton> getSecondButtons() {
+ return Arrays.asList(secondButton, secondButtonRtl);
+ }
+
+ /** Get the third action button used in the current orientation drawer. */
public CheckableImageButton getThirdButton() {
- return thirdButton;
+ return isDrawingFromRight() ? thirdButtonRtl : thirdButton;
+ }
+
+ /** Get both of the third action buttons from both LTR/RTL drawers. */
+ public List<CheckableImageButton> getThirdButtons() {
+ return Arrays.asList(thirdButton, thirdButtonRtl);
}
+ /** Get the correct expanded view used in current bubble orientation. */
public View getExpandedView() {
- return expandedView;
+ return isDrawingFromRight() ? expandedViewRtl : expandedView;
}
+ /** Get both views of the LTR and RTL drawers. */
+ public List<View> getExpandedViews() {
+ return Arrays.asList(expandedView, expandedViewRtl);
+ }
+
+ /** Get the correct shadow provider view used in current bubble orientation. */
public View getShadowProvider() {
- return shadowProvider;
+ return isDrawingFromRight() ? shadowProviderRtl : shadowProvider;
}
public void setDrawerVisibility(int visibility) {
- expandedView.setVisibility(visibility);
- shadowProvider.setVisibility(visibility);
+ if (isDrawingFromRight()) {
+ expandedViewRtl.setVisibility(visibility);
+ shadowProviderRtl.setVisibility(visibility);
+ } else {
+ expandedView.setVisibility(visibility);
+ shadowProvider.setVisibility(visibility);
+ }
}
public boolean isMoving() {
diff --git a/java/com/android/bubble/res/layout/bubble_base.xml b/java/com/android/bubble/res/layout/bubble_base.xml
index 3b5735cd0..0712db603 100644
--- a/java/com/android/bubble/res/layout/bubble_base.xml
+++ b/java/com/android/bubble/res/layout/bubble_base.xml
@@ -33,6 +33,19 @@
android:elevation="10dp"
android:visibility="invisible"
/>
+ <View
+ android:id="@+id/bubble_drawer_shadow_provider_rtl"
+ android:layout_width="@dimen/bubble_size"
+ android:layout_height="@dimen/bubble_size"
+ android:layout_marginTop="@dimen/bubble_shadow_padding_size"
+ android:layout_marginBottom="@dimen/bubble_shadow_padding_size"
+ android:layout_marginRight="@dimen/bubble_shadow_padding_size"
+ android:layout_gravity="right"
+ android:background="@drawable/bubble_ripple_circle"
+ android:backgroundTint="@android:color/transparent"
+ android:elevation="10dp"
+ android:visibility="invisible"
+ />
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -49,7 +62,7 @@
android:paddingStart="32dp"
android:paddingEnd="8dp"
android:background="@drawable/bubble_background_pill_ltr"
- android:layoutDirection="inherit"
+ android:layoutDirection="ltr"
android:orientation="horizontal"
android:visibility="gone"
tools:backgroundTint="#FF0000FF"
@@ -87,6 +100,58 @@
</LinearLayout>
</FrameLayout>
<FrameLayout
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="48dp"
+ android:elevation="10dp"
+ android:paddingTop="@dimen/bubble_shadow_padding_size"
+ android:paddingBottom="@dimen/bubble_shadow_padding_size"
+ android:paddingLeft="@dimen/bubble_shadow_padding_size">
+ <LinearLayout
+ android:id="@+id/bubble_expanded_layout_rtl"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="32dp"
+ android:paddingLeft="8dp"
+ android:background="@drawable/bubble_background_pill_rtl"
+ android:layoutDirection="rtl"
+ android:orientation="horizontal"
+ android:visibility="gone"
+ tools:backgroundTint="#FF0000FF"
+ tools:visibility="invisible">
+ <com.android.bubble.CheckableImageButton
+ android:id="@+id/bubble_icon_first_rtl"
+ android:layout_width="@dimen/bubble_size"
+ android:layout_height="@dimen/bubble_size"
+ android:layout_marginRight="4dp"
+ android:padding="@dimen/bubble_icon_padding"
+ android:tint="@color/bubble_icon_tint_states"
+ android:tintMode="src_in"
+ tools:background="@drawable/bubble_ripple_checkable_circle"
+ tools:src="@android:drawable/ic_lock_idle_lock"/>
+ <com.android.bubble.CheckableImageButton
+ android:id="@+id/bubble_icon_second_rtl"
+ android:layout_width="@dimen/bubble_size"
+ android:layout_height="@dimen/bubble_size"
+ android:layout_marginRight="4dp"
+ android:padding="@dimen/bubble_icon_padding"
+ android:tint="@color/bubble_icon_tint_states"
+ android:tintMode="src_in"
+ tools:background="@drawable/bubble_ripple_checkable_circle"
+ tools:src="@android:drawable/ic_input_add"/>
+ <com.android.bubble.CheckableImageButton
+ android:id="@+id/bubble_icon_third_rtl"
+ android:layout_width="@dimen/bubble_size"
+ android:layout_height="@dimen/bubble_size"
+ android:layout_marginRight="4dp"
+ android:padding="@dimen/bubble_icon_padding"
+ android:tint="@color/bubble_icon_tint_states"
+ android:tintMode="src_in"
+ tools:background="@drawable/bubble_ripple_checkable_circle"
+ tools:src="@android:drawable/ic_menu_call"/>
+ </LinearLayout>
+ </FrameLayout>
+ <FrameLayout
android:id="@+id/bubble_primary_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"