安卓NavigationView如何实现圆角效果

8
我正在设计一个定制的抽屉(Drawer),运行在 Android 上,它必须有上下圆角。我首先对上方进行了自定义,但是我发现问题在于该形状的背景不透明。
我有以下截图:
screenshot
(来源: toile-libre.org) 我需要实现以下设计:
design
(来源: toile-libre.org) 我也需要一些关于如何将其在底部倒角的帮助。

nav_header_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="@dimen/nav_header_height"
    android:background="@drawable/side_nav_bar"
    android:gravity="bottom"
    android:orientation="vertical"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:theme="@style/ThemeOverlay.AppCompat.Dark">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="0dp"
            android:layout_weight="4"
            android:layout_height="wrap_content"
            android:contentDescription="@string/nav_header_desc"
            android:paddingTop="@dimen/nav_header_vertical_spacing"
            app:srcCompat="@mipmap/ic_launcher_round" />
        <LinearLayout
            android:layout_width="0dp"
            android:layout_weight="5"
            android:layout_height="wrap_content"
            android:orientation="vertical">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingTop="@dimen/nav_header_vertical_spacing"
                android:text="@string/nav_header_title"
                android:textColor="@color/colorWhite"
android:textAppearance="@style/TextAppearance.AppCompat.Headline" />
            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/colorWhite"
                android:text="@string/nav_header_subtitle" />
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

side_nav_bar.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:width="3dp"
    android:color="@color/colorPrimary"
    />
<corners android:radius="1dp"
    android:bottomRightRadius="0dp" android:bottomLeftRadius="0dp"
    android:topLeftRadius="30dp" android:topRightRadius="0dp"/>
</shape>
5个回答

12
如果您正在使用Material Components库中的NavigationView,则可以将自定义ShapeAppearanceModel应用于您的NavigationView角落。例如:
float radius = getResources().getDimension(R.dimen.roundcorner);
NavigationView navigationView = findViewById(R.id.nav_view);
MaterialShapeDrawable navViewBackground = (MaterialShapeDrawable) navigationView.getBackground();
    navViewBackground.setShapeAppearanceModel(
        navViewBackground.getShapeAppearanceModel()
            .toBuilder()
            .setTopRightCorner(CornerFamily.ROUNDED,radius)
            .setBottomRightCorner(CornerFamily.ROUNDED,radius)
            .build());

这样NavigationView就有了圆角。
现在你需要注意头部布局,以便在顶部建立一个圆角。你需要使用以下内容作为头部视图的背景:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/side_nav_bar" 
    ...>

侧边导航栏的位置

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
     ....
     <corners android:topRightRadius="32dp" />
</shape>

不要在底部使用圆角,因为它只用于NavigationView的标题视图。

enter image description here

ShapeAppearanceModel需要使用1.1.0版本的Material组件(当前版本为'com.google.android.material:material:1.1.0-alpha10'


2

您可以将此行代码添加到NavigationView中:

app:drawerLayoutCornerSize="xdp"

1
在 Kotlin 语言中创建一个类来制作扩展:
fun MaterialNavigationView.changeCornerRadius() {
    val navViewBackground : MaterialShapeDrawable = background as MaterialShapeDrawable
    val radius = resources.getDimension(R.dimen.menu_radius)
    navViewBackground.shapeAppearanceModel = navViewBackground.shapeAppearanceModel
        .toBuilder()
        .setTopLeftCorner(CornerFamily.ROUNDED, radius)
        .setBottomLeftCorner(CornerFamily.ROUNDED, radius)
        .build()
}

使用方法:

val materialNavigationView: MaterialNavigationView = findViewById(R.id.material_navigation_view)
materialNavigationView.changeCornerRadius()

0

如果您不想使用MaterialShapeDrawable,可以尝试以下方法。我认为这也是最好的方法。

首先,调整导航视图背景的不透明度。其次,将导航视图内部的布局圆角化。

❖ 但是,请注意顶部和底部视图的背景。

layout_gnb.xml

<com.google.android.material.navigation.NavigationView
xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/NAVIGATION_VIEW"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#00000000">

    <LinearLayout
        android:id="@+id/LINEAR_LAYOUT_03"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:background="@drawable/rounded_right_corner_light_white_rectangle">
    ...
    </LinearLayout>

</com.google.android.material.navigation.NavigationView>

rounded_right_corner_light_white_rectangle.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:topRightRadius="30dp" 
             android:bottomRightRadius="30dp" />
    <solid android:color="@color/colorLightWhite" />
</shape>

0
添加左下角半径。
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<solid android:width="3dp"
    android:color="@color/colorPrimary"
    />
<corners android:radius="1dp"
    android:bottomRightRadius="0dp" android:bottomLeftRadius="30dp"
    android:topLeftRadius="30dp" android:topRightRadius="0dp"/>
</shape>

无法这样工作,因为它是headerView的背景,而不是整个navigationView的背景。 - Gabriele Mariotti

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接