Skip to content

Commit c2c660b

Browse files
imhappileticiarossi
authored andcommitted
[SearchBar] Update centering layout logic to account for padding and content insets
PiperOrigin-RevId: 751477468
1 parent 4f55422 commit c2c660b

File tree

2 files changed

+42
-41
lines changed

2 files changed

+42
-41
lines changed

lib/java/com/google/android/material/search/SearchBar.java

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -146,8 +146,6 @@ public class SearchBar extends Toolbar {
146146
private final Drawable defaultNavigationIcon;
147147
private final boolean tintNavigationIcon;
148148
private final boolean forceDefaultNavigationOnClickListener;
149-
private final int minimumTextMarginStart;
150-
private int currentTextMarginStart;
151149
@Nullable private View centerView;
152150
@Nullable private Integer navigationIconTint;
153151
@Nullable private Drawable originalNavigationIconBackground;
@@ -157,6 +155,7 @@ public class SearchBar extends Toolbar {
157155
private boolean textCentered;
158156
private int maxWidth;
159157
@Nullable private ActionMenuView menuView;
158+
@Nullable private ImageButton navIconButton;
160159

161160
private final LiftOnScrollProgressListener liftColorListener =
162161
new LiftOnScrollProgressListener() {
@@ -185,9 +184,6 @@ public SearchBar(@NonNull Context context, @Nullable AttributeSet attrs, int def
185184
context = getContext();
186185
validateAttributes(attrs);
187186

188-
minimumTextMarginStart =
189-
getResources()
190-
.getDimensionPixelSize(R.dimen.m3_searchbar_text_margin_start_no_navigation_icon);
191187
defaultNavigationIcon =
192188
AppCompatResources.getDrawable(context, getDefaultNavigationIconResource());
193189
searchBarAnimationHelper = new SearchBarAnimationHelper();
@@ -427,7 +423,7 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
427423
super.onLayout(changed, left, top, right, bottom);
428424

429425
if (centerView != null) {
430-
layoutViewInCenter(centerView, /* overlapMenu= */ true);
426+
layoutViewInCenter(centerView, /* absolutePlacement= */ true);
431427
}
432428
setHandwritingBoundsInsets();
433429
if (textView != null) {
@@ -436,37 +432,9 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
436432
// to be pushed to the side. In this case, we want the textview to be still centered on top of
437433
// any center views.
438434
if (textCentered) {
439-
layoutViewInCenter(textView, /* overlapMenu= */ false);
435+
layoutViewInCenter(textView, /* absolutePlacement= */ false);
440436
}
441-
// If after laying out, there's not enough space between the textview and the start of
442-
// the SearchBar, we add a margin.
443-
Toolbar.LayoutParams lp = (LayoutParams) textView.getLayoutParams();
444-
int currentMargin = lp.getMarginStart();
445-
int newMargin = getNewMargin(currentMargin);
446-
if (currentMargin != newMargin) {
447-
lp.setMarginStart(newMargin);
448-
currentTextMarginStart = newMargin;
449-
textView.setLayoutParams(lp);
450-
}
451-
}
452-
}
453-
454-
private int getNewMargin(int currentMargin) {
455-
// The start position of the textview with respect to its parent, the searchbar.
456-
int textViewStart =
457-
getLayoutDirection() == LAYOUT_DIRECTION_RTL
458-
? getMeasuredWidth() - textView.getRight()
459-
: textView.getLeft();
460-
int additionalMarginStart = max(minimumTextMarginStart - textViewStart, 0);
461-
// If we are already including the margin in the textview start, and it is necessary to be added
462-
// (ie. keeping the desired distance between the textview and the start), we should keep
463-
// the margin.
464-
if (currentTextMarginStart != 0
465-
&& currentMargin == currentTextMarginStart
466-
&& (textViewStart - currentMargin) < minimumTextMarginStart) {
467-
additionalMarginStart = currentMargin;
468437
}
469-
return additionalMarginStart;
470438
}
471439

472440
/**
@@ -605,22 +573,30 @@ private ActionMenuView findOrGetMenuView() {
605573
return menuView;
606574
}
607575

576+
@Nullable
577+
private ImageButton findOrGetNavView() {
578+
if (navIconButton == null) {
579+
navIconButton = ToolbarUtils.getNavigationIconButton(this);
580+
}
581+
return navIconButton;
582+
}
583+
608584
/**
609585
* Lays out the given view in the center of the {@link SearchBar}.
610586
*
611587
* @param view The view to layout in the center.
612-
* @param overlapMenu Whether the view can overlap the menu. This should be true if your centered
613-
* view should be absolute (eg. a product logo)
588+
* @param absolutePlacement Whether the view will be placed absolutely in the center (eg. ignoring
589+
* other toolbar elements like the nav icon and menu, padding, content insets)
614590
*/
615-
private void layoutViewInCenter(View view, boolean overlapMenu) {
591+
private void layoutViewInCenter(View view, boolean absolutePlacement) {
616592
if (view == null) {
617593
return;
618594
}
619595

620596
int viewWidth = view.getMeasuredWidth();
621597
int left = getMeasuredWidth() / 2 - viewWidth / 2;
622598
int right = left + viewWidth;
623-
if (!overlapMenu) {
599+
if (!absolutePlacement) {
624600
View menuView = findOrGetMenuView();
625601
if (menuView != null) {
626602
int diff =
@@ -630,13 +606,37 @@ private void layoutViewInCenter(View view, boolean overlapMenu) {
630606
left -= diff;
631607
right -= diff;
632608
}
633-
}
609+
View navIcon = findOrGetNavView();
610+
if (navIcon != null) {
611+
int diff =
612+
getLayoutDirection() == LAYOUT_DIRECTION_RTL
613+
? max(right - navIcon.getLeft(), 0)
614+
: max(navIcon.getRight() - left, 0);
615+
left += diff;
616+
right += diff;
617+
}
634618

619+
// Make sure to not lay out the view inside the SearchBar padding. paddingLeftAdded and
620+
// paddingRightAdded will never be non-zero at the same time, as Toolbar.measure has already
621+
// measured the children accounting for padding.
622+
int paddingStartAdded = max(getPaddingStart() - left, getContentInsetStart() - left);
623+
int paddingEndAdded =
624+
max(
625+
right - (getMeasuredWidth() - getPaddingEnd()),
626+
right - (getMeasuredWidth() - getContentInsetEnd()));
627+
left += max(paddingStartAdded, 0) - max(paddingEndAdded, 0);
628+
right += max(paddingStartAdded, 0) - max(paddingEndAdded, 0);
629+
}
635630
int viewHeight = view.getMeasuredHeight();
636631
int top = getMeasuredHeight() / 2 - viewHeight / 2;
637632
int bottom = top + viewHeight;
638633

639-
layoutChild(view, left, top, right, bottom);
634+
layoutChild(
635+
view,
636+
left,
637+
top,
638+
right,
639+
bottom);
640640
}
641641

642642
private void layoutChild(View child, int left, int top, int right, int bottom) {

lib/java/com/google/android/material/search/res/values/styles.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
<item name="defaultMarginsEnabled">true</item>
2828
<item name="defaultScrollFlagsEnabled">true</item>
2929
<item name="hideNavigationIcon">false</item>
30+
<item name="contentInsetStart">@dimen/m3_searchbar_text_margin_start_no_navigation_icon</item>
3031
<item name="shapeAppearance">?attr/shapeAppearanceMediumComponent</item>
3132
<item name="shapeAppearanceOverlay">@style/ShapeAppearanceOverlay.Material3.SearchBar</item>
3233
<item name="materialThemeOverlay">@style/ThemeOverlay.Material3.Search</item>

0 commit comments

Comments
 (0)