Skip to content

Commit

Permalink
[NavigationRail] Add new attributes for NavigationRail to control the…
Browse files Browse the repository at this point in the history
… top margin of the nav rail content, and the margin in between the optional header and the menu items

PiperOrigin-RevId: 637957360
  • Loading branch information
imhappi authored and pekingme committed Jun 5, 2024
1 parent e4f00fd commit 801ccab
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 12 deletions.
14 changes: 11 additions & 3 deletions docs/components/NavigationRail.md
Original file line number Diff line number Diff line change
Expand Up @@ -297,14 +297,22 @@ The following is an anatomy diagram for the navigation rail:

#### Header attributes

**Element** | **Attribute** | **Related methods** | **Default value**
--------------- | ------------------ | ---------------------------------------------------------- | -----------------
**Header view** | `app:headerLayout` | `addHeaderView`<br/>`removeHeaderView`<br/>`getHeaderView` | N/A
**Element** | **Attribute** | **Related methods** | **Default value**
------------------------ | ------------------------ | ---------------------------------------------------------- | -----------------
**Header view** | `app:headerLayout` | `addHeaderView`<br/>`removeHeaderView`<br/>`getHeaderView` | N/A
**Header bottom margin** | `app:headerMarginBottom` | N/A | `8dp`

See the
[FAB documentation](https://github.com/material-components/material-components-android/tree/master/docs/components/FloatingActionButton.md)
for more attributes.

#### Navigation Menu attributes

**Element** | **Attribute** | **Related methods** | **Default value**
---------------- | ---------------------- | ------------------------------------- | -----------------
**Menu gravity** | `app:menuGravity` | `setMenuGravity`<br/>`getMenuGravity` | `TOP\|CENTER_HORIZONTAL`
**Top margin** | `app:contentMarginTop` | N/A | N/A

#### Navigation item attributes

**Element** | **Attribute** | **Related methods** | **Default value**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import static java.lang.Math.min;

import android.content.Context;
import android.content.res.Resources;
import androidx.appcompat.widget.TintTypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
Expand Down Expand Up @@ -108,7 +107,8 @@ public class NavigationRailView extends NavigationBarView {
private static final int DEFAULT_HEADER_GRAVITY = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
static final int NO_ITEM_MINIMUM_HEIGHT = -1;

private final int topMargin;
private final int contentMarginTop;
private final int headerMarginBottom;
@Nullable private View headerView;
@Nullable private Boolean paddingTopSystemWindowInsets = null;
@Nullable private Boolean paddingBottomSystemWindowInsets = null;
Expand All @@ -131,9 +131,6 @@ public NavigationRailView(
@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);

final Resources res = getResources();
topMargin = res.getDimensionPixelSize(R.dimen.mtrl_navigation_rail_margin);

// Ensure we are using the correctly themed context rather than the context that was passed in.
context = getContext();

Expand All @@ -142,6 +139,13 @@ public NavigationRailView(
ThemeEnforcement.obtainTintedStyledAttributes(
context, attrs, R.styleable.NavigationRailView, defStyleAttr, defStyleRes);

contentMarginTop =
attributes.getDimensionPixelSize(R.styleable.NavigationRailView_contentMarginTop,
getResources().getDimensionPixelSize(R.dimen.mtrl_navigation_rail_margin));
headerMarginBottom =
attributes.getDimensionPixelSize(R.styleable.NavigationRailView_headerMarginBottom,
getResources().getDimensionPixelSize(R.dimen.mtrl_navigation_rail_margin));

int headerLayoutRes = attributes.getResourceId(R.styleable.NavigationRailView_headerLayout, 0);
if (headerLayoutRes != 0) {
addHeaderView(headerLayoutRes);
Expand Down Expand Up @@ -236,7 +240,8 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(minWidthSpec, heightMeasureSpec);

if (isHeaderViewVisible()) {
int maxMenuHeight = getMeasuredHeight() - headerView.getMeasuredHeight() - topMargin;
int maxMenuHeight = getMeasuredHeight() - headerView.getMeasuredHeight() - contentMarginTop
- headerMarginBottom;
int menuHeightSpec = MeasureSpec.makeMeasureSpec(maxMenuHeight, MeasureSpec.AT_MOST);
measureChild(getNavigationRailMenuView(), minWidthSpec, menuHeightSpec);
}
Expand All @@ -249,13 +254,13 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
NavigationRailMenuView menuView = getNavigationRailMenuView();
int offsetY = 0;
if (isHeaderViewVisible()) {
int usedTop = headerView.getBottom() + topMargin;
int usedTop = headerView.getBottom() + headerMarginBottom;
int menuTop = menuView.getTop();
if (menuTop < usedTop) {
offsetY = usedTop - menuTop;
}
} else if (menuView.isTopGravity()) {
offsetY = topMargin;
offsetY = contentMarginTop;
}

if (offsetY > 0) {
Expand Down Expand Up @@ -296,7 +301,7 @@ public void addHeaderView(@NonNull View headerView) {

FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT);
params.gravity = DEFAULT_HEADER_GRAVITY;
params.topMargin = topMargin;
params.topMargin = contentMarginTop;
addView(headerView, /* index= */ 0, params);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
<public name="itemMinHeight" type="attr"/>
<public name="navigationRailStyle" type="attr"/>
<public name="menuGravity" type="attr"/>
<public name="contentMarginTop" type="attr"/>
<public name="headerMarginBottom" type="attr"/>
<public name="Widget.MaterialComponents.NavigationRailView" type="style"/>
<public name="Widget.MaterialComponents.NavigationRailView.Compact" type="style"/>
<public name="Widget.MaterialComponents.NavigationRailView.Colored" type="style"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
<attr name="itemMinHeight" format="dimension"/>
<!-- Specifies the layout that will be used to create the header view, if any -->
<attr name="headerLayout"/>
<!-- The bottom margin of the header -->
<attr name="headerMarginBottom" format="dimension"/>
<!-- The top margin of the content of the navigation rail. -->
<attr name="contentMarginTop" format="dimension"/>
<!-- Specifies how the navigation rail destinations should be aligned as a group. -->
<attr name="menuGravity">
<!-- Navigation rail destinations will be aligned as a group at the top. This is the default behavior. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
<item name="labelVisibilityMode">auto</item>
<item name="menuGravity">top</item>
<item name="android:fitsSystemWindows">true</item>
<item name="contentMarginTop">@dimen/mtrl_navigation_rail_margin</item>
<item name="headerMarginBottom">@dimen/mtrl_navigation_rail_margin</item>
</style>

<style name="Widget.MaterialComponents.NavigationRailView.Compact">
Expand Down

0 comments on commit 801ccab

Please sign in to comment.