一、Toolbar

1.去除系统自动标题栏

在以下路径中找到两个themes.xml文件:{项目名}\app\src\main\res\values\themes.xml

将style中的DarkActionBar改为NoActionBar

<style name="Theme.MaterialDesign" parent="Theme.MaterialComponents.DayNight.NoActionBar">

2.在主活动布局文件中创建toolbar

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/black"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

</FrameLayout>

3.创建menu资源文件夹,在menu下创建toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/xiaoxi"
        android:icon="@drawable/xiaoxi"
        android:title="Backup"
        app:showAsAction="always"/>
    <item
        android:id="@+id/guoqi"
        android:icon="@drawable/guoqi"
        android:title="Delete"
        app:showAsAction="ifRoom"/>

</menu>

4.修改主活动文件

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar, menu);
        return true;
    }
    public boolean onOptionsItemSelected(MenuItem item) {
        if(R.id.xiaoxi == item.getItemId()){
            Toast.makeText(this,"B",Toast.LENGTH_SHORT).show();
        }else if(R.id.guoqi == item.getItemId()){
            Toast.makeText(this,"D",Toast.LENGTH_SHORT).show();
        }
        return true;
    }
}

二、DrawerLayout

1.修改主活动的布局文件

使用androidx.drawerlayout.widget.DrawerLayout

第一个子控件是主屏幕显示的内容,第二个子控件是滑动菜单中显示的内容

<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@color/black"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </FrameLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:text="Menu"
        android:textSize="30sp"
        android:background="#FFF"/>

</androidx.drawerlayout.widget.DrawerLayout>

2.修改主活动文件

1. DrawerLayout 声明

private DrawerLayout drawerLayout;
  • 声明一个 DrawerLayout 类型的成员变量

  • DrawerLayout 是 Android Support 库中实现侧滑菜单的布局容器

2. 初始化 DrawerLayout

    drawerLayout = (DrawerLayout) findViewById(R.id.main);
  • 通过 findViewById(R.id.main) 获取布局文件中定义的 DrawerLayout

  • 这里假设布局文件中有一个 ID 为 main 的 DrawerLayout

3. 设置导航按钮

ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
    actionBar.setDisplayHomeAsUpEnabled(true);      // 显示返回/菜单图标
    actionBar.setHomeAsUpIndicator(R.drawable.xiaoxi); // 设置自定义图标
}
  • setDisplayHomeAsUpEnabled(true):在 ActionBar 左侧显示导航图标

  • setHomeAsUpIndicator(R.drawable.xiaoxi):将默认图标替换为自定义图标

4. 处理导航按钮点击事件

public boolean onOptionsItemSelected(MenuItem item) {
    // ... 其他菜单项处理 ...
    else if(android.R.id.home == item.getItemId()){  // 点击导航按钮
        drawerLayout.openDrawer(GravityCompat.START);  // 打开侧滑菜单
    }
    return true;
}
  • android.R.id.home:系统定义的导航按钮 ID

  • drawerLayout.openDrawer(GravityCompat.START):从左侧打开侧滑菜单

三、NavigationView

用于优化滑动菜单页面

1.创建文件

分别创建一个menu/nav_menu和layout/nav_header的xml文件

nav_menu代码如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/nav_call"
            android:icon="@drawable/xiaoxi"
            android:title="Call"/>
        <item
            android:id="@+id/nav_friends"
            android:icon="@drawable/xiaoxi"
            android:title="Friends"/>
        <item
            android:id="@+id/nav_location"
            android:icon="@drawable/xiaoxi"
            android:title="Location"/>
        <item
            android:id="@+id/nav_mail"
            android:icon="@drawable/xiaoxi"
            android:title="Mail"/>
        <item
            android:id="@+id/nav_task"
            android:icon="@drawable/xiaoxi"
            android:title="Task"/>
    </group>

</menu>

nav_header代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:padding="10dp"
    android:background="?attr/colorPrimary">

    <ImageView
        android:id="@+id/image"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:src="@drawable/ic_launcher_background"
        android:layout_centerInParent="true"/>

    <TextView
        android:id="@+id/username"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="tangjunhui@gmail.com"
        android:textColor="#FFF"
        android:textSize="14sp"/>
    <TextView
        android:id="@+id/mail"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/username"
        android:text="Jack"
        android:textColor="#FFF"
        android:textSize="14sp"/>

</RelativeLayout>

2.修改主活动布局文件

在主活动布局文件中,用NavigationView控件替换之前所写的菜单显示的内容

可以传入两个值将nav_menu和nav_header俩个文件结合

<com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        app:menu="@menu/nav_menu"
        app:headerLayout="@layout/nav_header"/>

3.在主活动文件中监听点击事件

完整代码如下:

public class MainActivity extends AppCompatActivity {
    private DrawerLayout drawerLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = (DrawerLayout) findViewById(R.id.main);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.xiaoxi);
        }
        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setCheckedItem(R.id.nav_call);
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                drawerLayout.closeDrawers();
                return false;
            }
        });
    }

    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar, menu);
        return true;
    }
    public boolean onOptionsItemSelected(MenuItem item) {
        if(R.id.xiaoxi == item.getItemId()){
            Toast.makeText(this,"B",Toast.LENGTH_SHORT).show();
        }else if(R.id.guoqi == item.getItemId()){
            Toast.makeText(this,"D",Toast.LENGTH_SHORT).show();
        }else if(android.R.id.home == item.getItemId()){
            drawerLayout.openDrawer(GravityCompat.START);
        }
        return true;
    }
}

四、FloatingActionButton

用来实现悬浮效果

app:elevation给定悬浮的高度值,高度越高阴影越大

<com.google.android.material.floatingactionbutton.FloatingActionButton
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@mipmap/ic_launcher"
            app:elevation="20dp" />

五、Snackbar

我们为刚刚的悬浮按钮添加点击事件,使用Snackbar

Snackbar是Material Design中提供的更先进的提示方法,区别于Toast

特性 Snackbar Toast
出现位置 屏幕底部 屏幕任意位置(通常底部)
用户交互 ✅ 可交互(可包含操作按钮) ❌ 不可交互
自动消失时间 可设置(默认较短) 固定(LENGTH_SHORT/LONG)
显示上下文 附着在特定 View 上 全局显示,与具体 View 无关
消失方式 自动消失  用户滑动消失 只能自动消失
Material Design ✅ 是 Material Design 组件 ❌ 不是
父类依赖 需要 CoordinatorLayout 实现高级功能 无特殊依赖
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Snackbar.make(v,"Data deleted",Snackbar.LENGTH_SHORT)
                        .setAction("UNDO", new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                Toast.makeText(MainActivity.this,"Data restored",Toast.LENGTH_SHORT).show();
                            }
                        }).show();
            }
        });

六、CoordinatorLayout

上述代码运行时弹出的Snackbar会遮挡悬浮按钮

我们可以将主活动布局文件中的<FrameLayout>替换为<CoordinatorLayout>即可

CoordinatorLayout会自动检测弹出位置,并自动偏移悬浮按钮

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐