diff --git a/lib/java/com/google/android/material/navigation/NavigationBarItemView.java b/lib/java/com/google/android/material/navigation/NavigationBarItemView.java index 710c1100a79..c4957cd896b 100644 --- a/lib/java/com/google/android/material/navigation/NavigationBarItemView.java +++ b/lib/java/com/google/android/material/navigation/NavigationBarItemView.java @@ -46,6 +46,7 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; +import android.view.View.OnLongClickListener; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; @@ -161,6 +162,9 @@ public abstract class NavigationBarItemView extends FrameLayout private int activeIndicatorExpandedMarginHorizontal = 0; @Nullable private BadgeDrawable badgeDrawable; + @Nullable private CharSequence tooltipText; + @Nullable private OnLongClickListener customOnLongClickListener; + private boolean settingTooltipCompatLongClickListener; @ItemIconGravity private int itemIconGravity; private int badgeFixedEdge = BadgeDrawable.BADGE_FIXED_EDGE_START; @@ -291,10 +295,7 @@ public void initialize(@NonNull MenuItemImpl itemData, int menuType) { ? itemData.getTooltipText() : itemData.getTitle(); - // Avoid calling tooltip for L and M devices because long pressing twice may freeze devices. - if (VERSION.SDK_INT > VERSION_CODES.M) { - TooltipCompat.setTooltipText(this, tooltipText); - } + setItemTooltipText(tooltipText); updateVisibility(); this.initialized = true; } @@ -482,9 +483,41 @@ public void setTitle(@Nullable CharSequence title) { itemData == null || TextUtils.isEmpty(itemData.getTooltipText()) ? title : itemData.getTooltipText(); + setItemTooltipText(tooltipText); + } + + @Override + public void setOnLongClickListener(@Nullable OnLongClickListener listener) { + if (settingTooltipCompatLongClickListener) { + super.setOnLongClickListener(listener); + return; + } + + customOnLongClickListener = listener; + super.setOnLongClickListener(listener); + updateTooltipText(); + } + + private void setItemTooltipText(@Nullable CharSequence tooltipText) { + this.tooltipText = tooltipText; + updateTooltipText(); + } + + private void updateTooltipText() { // Avoid calling tooltip for L and M devices because long pressing twice may freeze devices. - if (VERSION.SDK_INT > VERSION_CODES.M) { - TooltipCompat.setTooltipText(this, tooltipText); + if (VERSION.SDK_INT <= VERSION_CODES.M) { + return; + } + + if (VERSION.SDK_INT >= VERSION_CODES.O) { + setTooltipText(tooltipText); + } else if (customOnLongClickListener == null) { + settingTooltipCompatLongClickListener = true; + try { + TooltipCompat.setTooltipText(this, tooltipText); + } finally { + settingTooltipCompatLongClickListener = false; + } } } diff --git a/lib/javatests/com/google/android/material/navigation/NavigationBarItemViewTest.java b/lib/javatests/com/google/android/material/navigation/NavigationBarItemViewTest.java index 238fd18f8f6..c0b34ff8694 100644 --- a/lib/javatests/com/google/android/material/navigation/NavigationBarItemViewTest.java +++ b/lib/javatests/com/google/android/material/navigation/NavigationBarItemViewTest.java @@ -17,6 +17,7 @@ import com.google.android.material.test.R; +import static android.os.Build.VERSION_CODES.N; import static android.os.Build.VERSION_CODES.O; import static com.google.common.truth.Truth.assertThat; @@ -80,6 +81,25 @@ public void testSetTitle_updatesTooltip() { assertThat(itemView.getTooltipText().toString()).isEqualTo(updatedTitle); } + @Test + @Config(sdk = N) + public void testPreOLongClickListener_preservedAfterTitleUpdate() { + MenuItemImpl menuItem = createMenuItemImpl("menu item title", null); + NavigationBarItemView itemView = new NavigationBarItemTestView(context); + itemView.initialize(menuItem, MENU_TYPE); + final boolean[] longClicked = new boolean[1]; + itemView.setOnLongClickListener( + v -> { + longClicked[0] = true; + return true; + }); + + itemView.setTitle("menu item title updated"); + + assertThat(itemView.performLongClick()).isTrue(); + assertThat(longClicked[0]).isTrue(); + } + private MenuItemImpl createMenuItemImpl(CharSequence title, CharSequence tooltip) { MenuBuilder builder = new MenuBuilder(context); builder.add(title);