diff options
Diffstat (limited to 'java')
-rw-r--r-- | java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java | 150 |
1 files changed, 115 insertions, 35 deletions
diff --git a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java index f5cdc4d87..9653f55ed 100644 --- a/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java +++ b/java/com/android/dialer/historyitemactions/HistoryItemActionBottomSheet.java @@ -28,13 +28,16 @@ import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; +import android.view.ViewTreeObserver.OnPreDrawListener; import android.view.Window; +import android.view.accessibility.AccessibilityManager; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import com.android.dialer.common.Assert; import com.android.dialer.theme.base.ThemeComponent; import com.android.dialer.widget.ContactPhotoView; +import com.google.common.collect.ImmutableSet; import java.util.List; /** @@ -49,6 +52,42 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O private final List<HistoryItemActionModule> modules; private final HistoryItemBottomSheetHeaderInfo historyItemBottomSheetHeaderInfo; + /** + * An {@link OnPreDrawListener} that sets the contact layout's elevation if + * + * <ul> + * <li>the bottom sheet can expand to full screen, and + * <li>the bottom sheet is fully expanded. + * </ul> + * + * <p>The reason an {@link OnPreDrawListener} instead of a {@link BottomSheetCallback} is used to + * handle this is that the initial state of the bottom sheet will be STATE_EXPANDED when the touch + * exploration (e.g., TalkBack) is enabled and {@link BottomSheetCallback} won't be triggered in + * this case. See {@link #setupBottomSheetBehavior()} for details. + */ + private final OnPreDrawListener onPreDrawListenerForContactLayout = + () -> { + View contactLayout = findViewById(R.id.contact_layout_root); + View background = findViewById(android.support.design.R.id.touch_outside); + View bottomSheet = findViewById(android.support.design.R.id.design_bottom_sheet); + + BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(bottomSheet); + + // If the height of the background is equal to that of the bottom sheet, the bottom sheet + // *can* be expanded to full screen. + contactLayout.setElevation( + background.getHeight() == bottomSheet.getHeight() + && behavior.getState() == BottomSheetBehavior.STATE_EXPANDED + ? getContext() + .getResources() + .getDimensionPixelSize(R.dimen.contact_actions_header_elevation) + : 0); + + return true; // Return true to proceed with the current drawing pass. + }; + + private LinearLayout contactLayout; + private HistoryItemActionBottomSheet( Context context, HistoryItemBottomSheetHeaderInfo historyItemBottomSheetHeaderInfo, @@ -71,6 +110,10 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O @Override protected void onCreate(Bundle bundle) { + contactLayout = Assert.isNotNull(findViewById(R.id.contact_layout_root)); + + initBottomSheetState(); + setupBottomSheetBehavior(); setupWindow(); setupContactLayout(); @@ -84,7 +127,68 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O } } - // Overrwrites the window size since Dialog's don't match parent. + @Override + public void onAttachedToWindow() { + super.onAttachedToWindow(); + contactLayout.getViewTreeObserver().addOnPreDrawListener(onPreDrawListenerForContactLayout); + } + + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + contactLayout.getViewTreeObserver().removeOnPreDrawListener(onPreDrawListenerForContactLayout); + } + + private void initBottomSheetState() { + // If the touch exploration in the system (e.g., TalkBack) is enabled, the bottom sheet should + // be fully expanded because sometimes services like TalkBack won't read all items when the + // bottom sheet is not fully expanded. + if (isTouchExplorationEnabled()) { + BottomSheetBehavior<View> behavior = + BottomSheetBehavior.from(findViewById(android.support.design.R.id.design_bottom_sheet)); + behavior.setState(BottomSheetBehavior.STATE_EXPANDED); + } + } + + /** + * Configures the bottom sheet behavior when its state changes. + * + * <p>If the touch exploration in the system (e.g., TalkBack) is enabled, the bottom sheet will be + * canceled if it is in a final state other than {@link BottomSheetBehavior#STATE_EXPANDED}. This + * is because sometimes services like TalkBack won't read all items when the bottom sheet is not + * fully expanded. + * + * <p>If the touch exploration is disabled, cancel the bottom sheet when it is in {@link + * BottomSheetBehavior#STATE_HIDDEN}. + */ + private void setupBottomSheetBehavior() { + BottomSheetBehavior<View> behavior = + BottomSheetBehavior.from(findViewById(android.support.design.R.id.design_bottom_sheet)); + behavior.setBottomSheetCallback( + new BottomSheetCallback() { + @Override + public void onStateChanged(@NonNull View bottomSheet, int newState) { + ImmutableSet<Integer> statesToCancelBottomSheet = + isTouchExplorationEnabled() + ? ImmutableSet.of( + BottomSheetBehavior.STATE_COLLAPSED, + BottomSheetBehavior.STATE_HIDDEN, + BottomSheetBehavior.STATE_HALF_EXPANDED) + : ImmutableSet.of(BottomSheetBehavior.STATE_HIDDEN); + + if (statesToCancelBottomSheet.contains(newState)) { + cancel(); + } + + // TODO(calderwoodra): set the status bar color when expanded, else translucent + } + + @Override + public void onSlide(@NonNull View bottomSheet, float slideOffset) {} + }); + } + + // Overwrites the window size since it doesn't match the parent. private void setupWindow() { Window window = getWindow(); if (window == null) { @@ -97,13 +201,11 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O } private void setupContactLayout() { - View contactView = Assert.isNotNull(findViewById(R.id.contact_layout_root)); - - ContactPhotoView contactPhotoView = contactView.findViewById(R.id.contact_photo_view); + ContactPhotoView contactPhotoView = contactLayout.findViewById(R.id.contact_photo_view); contactPhotoView.setPhoto(historyItemBottomSheetHeaderInfo.getPhotoInfo()); - TextView primaryTextView = contactView.findViewById(R.id.primary_text); - TextView secondaryTextView = contactView.findViewById(R.id.secondary_text); + TextView primaryTextView = contactLayout.findViewById(R.id.primary_text); + TextView secondaryTextView = contactLayout.findViewById(R.id.secondary_text); primaryTextView.setText(historyItemBottomSheetHeaderInfo.getPrimaryText()); if (!TextUtils.isEmpty(historyItemBottomSheetHeaderInfo.getSecondaryText())) { @@ -112,35 +214,6 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O secondaryTextView.setVisibility(View.GONE); secondaryTextView.setText(null); } - - View background = findViewById(android.support.design.R.id.touch_outside); - BottomSheetBehavior behavior = - BottomSheetBehavior.from(findViewById(android.support.design.R.id.design_bottom_sheet)); - behavior.setBottomSheetCallback( - new BottomSheetCallback() { - @Override - public void onStateChanged(@NonNull View bottomSheet, int newState) { - if (newState == BottomSheetBehavior.STATE_HIDDEN) { - cancel(); - return; - } - - // If the bottomsheet can expand to full screen, set the header's elevation when it's - // fully expanded. - if (background.getHeight() == bottomSheet.getHeight()) { - contactView.setElevation( - newState == BottomSheetBehavior.STATE_EXPANDED - ? getContext() - .getResources() - .getDimensionPixelSize(R.dimen.contact_actions_header_elevation) - : 0); - // TODO(calderwoodra): set the status bar color when expanded, else translucent - } - } - - @Override - public void onSlide(@NonNull View bottomSheet, float slideOffset) {} - }); } private View getDividerView(ViewGroup container) { @@ -170,4 +243,11 @@ public class HistoryItemActionBottomSheet extends BottomSheetDialog implements O dismiss(); } } + + private boolean isTouchExplorationEnabled() { + AccessibilityManager accessibilityManager = + getContext().getSystemService(AccessibilityManager.class); + + return accessibilityManager.isTouchExplorationEnabled(); + } } |