目录
3 FloatingActionButton 悬浮按钮和可交互提示
1.Toolbar
还记得我们每次打开的程序的标题栏吗?那不是 toolbar 做的 , 那是 actionbar 做的 , Toolbar 可以说是 Actionbar 的升级版了。 Toolbar 不仅有 Actionbar 的所有功能 , 而且还更加灵活 .
在项目运行在虚拟机上时,都可以看见屏幕上方有一个栏目(下图红框圈出的部分),此为系统默认的
DarkActionBar ,可在 themes.xml 中查看。

去掉系统默认栏目的的方法:

以便于我们更灵活的编辑栏目内容,所以我们先将主题文件中的 DarkActionBar
改为 NoActionBar ,再次运行就可以发现顶端的栏目不见了
1.1基本框架
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/drawer"
tools:context=".MainActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/teal_200"
app:navigationIcon="@drawable/ic_baseline_arrow_back_ios_24"
app:title="Xisq's APP"
app:titleTextColor="#2A91E3"
app:subtitle="Android学习笔记"
app:logo="@mipmap/logo"
app:titleMarginStart="60dp"
app:menu="@menu/toolbar_menu"/>
</androidx.drawerlayout.widget.DrawerLayout>注意尖括号里不是普通的 Toolbar ,而是 androidx.appcompat.widget.Toolbar 。
1.2常用属性
属性 | 说明 |
app:navigationIcon | 导航图标,一般情况下放回退按钮,点击退回上一个界面。 |
android:background | 工具栏颜色 |
app:title | 标题 |
app:titleTextColor | 标题文字颜色 |
app:titleMarginStart | 标题与左侧间距 |
app:subtitle | 子标题 |
app:subtitleTextColor | 子标题颜色 |
app:logo | 工具栏 logo |
1.3添加工具栏点击事件
给 Toolbar 加上 id ,我们就可以在 java 代码里获取并监听用户对工具栏图标的点击:
package com.hp.demo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show();
}
});
}
}1.4溢出菜单
首先我们在 res 的 menu 目录中创建一个 menu 资源文件 toolbar_menu.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/toolbar_user"
android:title="用户"
android:icon="@drawable/ic_baseline_perm_identity_24"
app:showAsAction="never"/>
<item android:id="@+id/toolbar_settings"
android:title="设置"
android:icon="@drawable/ic_baseline_settings_24"
app:showAsAction="never"/>
<item android:id="@+id/toolbar_add"
android:title="其他"
android:icon="@drawable/ic_baseline_add_24"
app:showAsAction="never"/>
</menu>1.5溢出菜单的点击事件
package com.hp.demo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private DrawerLayout drawer;
private NavigationView nv_nav;
private FloatingActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getGroupId()){
case 0:
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
}2 DrawerLayout滑动菜单
2.1基本框架
布局 ---- 在这个布局中允许放入两个直接子控件
屏幕中显示的内容
滑动菜单中显示的内容
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/drawer"
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/teal_200"
app:navigationIcon="@drawable/ic_baseline_arrow_back_ios_24"
app:title="Xisq's APP"
app:titleTextColor="#2A91E3"
app:subtitle="Android学习笔记"
app:logo="@mipmap/logo"
app:titleMarginStart="60dp"
app:menu="@menu/toolbar_menu"/>
</FrameLayout>
<!--滑动菜单中的内容--> <!--android:layout_gravity="start"指定了滑动菜单在屏幕的哪边
start是指系统语言是从左到右读就在右边,反之就在左边-->
<!--android:layout_gravity="start"必须要指定,指定了的就是滑动菜单-->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nv_nav"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_item"
app:headerLayout="@layout/nav_header"/>
</androidx.drawerlayout.widget.DrawerLayout>点击 Toolbar 的图标弹出滑出菜单
package com.hp.demo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private DrawerLayout drawer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
drawer=findViewById(R.id.drawer);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
drawer.openDrawer(GravityCompat.START);
}
});
}
}2.2 NavigationView
1.引入开源项目 CircleImageView, 可以轻松实现图片圆形化
dependencies {
···
implementation 'de.hdodenhof:circleimageview:3.0.1'
}2. 创建 menu ,作为滑动菜单 drawerlayout_men.xml
<?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_1"
android:title="朋友"
android:icon="@drawable/ic_baseline_accessibility_24"/>
<item android:id="@+id/nav_2"
android:title="位置"
android:icon="@drawable/ic_baseline_location_on_24"/>
<item android:id="@+id/nav_3"
android:title="记事本"
android:icon="@drawable/ic_baseline_event_note_24"/>
</group>
</menu>3. 在 layout 创建 headerLayout nav_header.xml
<?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="180dp"
android:background="#2196F3">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/civ_img"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@mipmap/tou"
android:layout_centerInParent="true"/>
<TextView
android:layout_below="@id/civ_img"
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:textColor="@color/white"
android:layout_centerHorizontal="true"
android:text="八嘎呀路" />
</RelativeLayout>4. 修改基本框架
<com.google.android.material.navigation.NavigationView
android:id="@+id/nv_nav"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_item"
app:headerLayout="@layout/nav_header"/>5. 给滑动菜单设置点击事件
private NavigationView nv_nav;
...
nv_nav=findViewById(R.id.nv_nav);
nv_nav.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if (item.getItemId()==R.id.nav_1){
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
}else if (item.getItemId()==R.id.nav_2){
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
}else if (item.getItemId()==R.id.nav_3){
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
}
return true;
}
});3 FloatingActionButton悬浮按钮和可交互提示
3.1基本框架
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#FFEB3B"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:elevation="8dp"
android:src="@drawable/ic_baseline_done_outline_24"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>4 Snackbar
Toast 提示是不是有点拉,可以用 Snackbar 提示。但是 Toast 并非是不如 Snackbar ,他们有不同的应用场景。Toast只能告诉用户现在发生了什么事情,用户只能被动接收这件事情。Snackbar允许在提示中加入一个可交互按钮,当用户点击按钮的时候,就可以执行一 些额外的逻辑操作
4.1基本框架
package com.hp.demo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity {
private FloatingActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fab=findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"删除数据",Snackbar.LENGTH_SHORT).setAction("取消", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "数据已恢复", Toast.LENGTH_SHORT).show();
}
}).show();
}
});
5 CoordinatorLayout
但是此时我们会发现 Snackbar 弹出的时候会把悬浮按钮遮住,但是这个问题我们可以用CoordinatorLayout 解决CoordinatorLayout可以是一种加强版的 FrameLayout( 帧布局 )CoordinatorLayout会监听所有子控件的各种事件,并且自动帮助我们做出最为合理的 响应
5.1基本框架
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/drawer"
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/teal_200"
app:navigationIcon="@drawable/ic_baseline_arrow_back_ios_24"
app:title="Xisq's APP"
app:titleTextColor="#2A91E3"
app:subtitle="Android学习笔记"
app:logo="@mipmap/logo"
app:titleMarginStart="60dp"
app:menu="@menu/toolbar_menu"/>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:backgroundTint="#FFEB3B"
android:id="@+id/fab"
android:layout_gravity="bottom|end"
android:layout_margin="16dp"
android:elevation="8dp"
android:src="@drawable/ic_baseline_done_outline_24"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</FrameLayout>
<!--滑动菜单中的内容--> <!--android:layout_gravity="start"指定了滑动菜单在屏幕的哪边
start是指系统语言是从左到右读就在右边,反之就在左边-->
<!--android:layout_gravity="start"必须要指定,指定了的就是滑动菜单-->
<com.google.android.material.navigation.NavigationView
android:id="@+id/nv_nav"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="@menu/nav_item"
app:headerLayout="@layout/nav_header"/>
</androidx.drawerlayout.widget.DrawerLayout>5.2具体用法
package com.hp.demo;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.navigation.NavigationView;
import com.google.android.material.snackbar.Snackbar;
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private DrawerLayout drawer;
private NavigationView nv_nav;
private FloatingActionButton fab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar=findViewById(R.id.toolbar);
drawer=findViewById(R.id.drawer);
nv_nav=findViewById(R.id.nv_nav);
fab=findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view,"删除数据",Snackbar.LENGTH_SHORT).setAction("取消", new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "数据已恢复", Toast.LENGTH_SHORT).show();
}
}).show();
}
});
nv_nav.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
if (item.getItemId()==R.id.nav_1){
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
}else if (item.getItemId()==R.id.nav_2){
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
}else if (item.getItemId()==R.id.nav_3){
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
}
return true;
}
});
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override public void onClick(View view) {
//Toast.makeText(MainActivity.this, "返回", Toast.LENGTH_SHORT).show();
drawer.openDrawer(GravityCompat.START);
}
});
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getGroupId()){
case 0:
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case 1:
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
case 2:
Toast.makeText(MainActivity.this, item.getTitle(), Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
}
}其实就是把原本的 FrameLayout 布局改成了 androidx.coordinatorlayout.widget.CoordinatorLayout 就行了效果就是当点击悬浮按钮 Snackbar 出现的时候,悬浮按钮会上移来适应 Snackbar 是自己不会被Snackbar 遮住但是 Snackbar 并不是 CoordinatorLayout 的子控件,而是 DrawerLayout 的子控件 , 为什么也能成功呢 ?是因为 Snackbar.make() 传入了一个 view, 这是用来指定 Snackbar 是哪个 View 触发的,所以传入的是悬浮按钮控件本身,悬浮按钮控件是 CoordinatorLayout 的子控件,所以能成功
版权声明:本文为weixin_63261150原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。