Material Design(ToolBar,滑动窗口,悬浮按钮和可交互提示)

1.Toolbar

系统原生的ActionBar由于其设计原因,被限定只能位于活动的顶部。Toolbar的强大之处在于,它不仅继承了ActionBar的所有功能,而且灵活性很高。

首先我们都知道,任何一个新建的项目,默认都会显示ActionBar的,这是根据项目中指定的主题来显示的。打开AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    ...
application>

可以看到android:theme属性指定了一个AppTheme主题。ctrl+鼠标左键点击AppTheme,会看到如下

<resources>

    
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        
        "colorPrimary">@color/colorPrimary
        "colorPrimaryDark">@color/colorPrimaryDark
        "colorAccent">@color/colorAccent
    style>

resources>

这里定义了一个叫做AppTheme的主题,然后指定它的parent主题是Theme.AppCompat.Light.DarkActionBar。这个DarkActionBar是一个深色的ActionBar主题。

现在我们准备使用ToolBar来替代ActionBar,需要指定一个不带ActionBar的主题,通常有Theme.AppCompat.Light.NoActionBar和Theme.AppCompat.NoActionBar

Theme.AppCompat.Light.NoActionBar:表示淡色主题,它会将界面的主体颜色设成淡色,陪衬颜色设成深色。

Theme.AppCompat.NoActionBar:表示深色主题,它会将界面的主体颜色设成深色,陪衬颜色设成淡色。

我们这里设置为淡色主题

<resources>

    
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        
        "colorPrimary">@color/colorPrimary
        "colorPrimaryDark">@color/colorPrimaryDark
        "colorAccent">@color/colorAccent
    style>

resources>

接下来看一看如何使用ToolBar

<FrameLayout 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="match_parent">

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

修改标题栏上显示的文字内容 android:label="Psycho"在AndroidManifest中

<activity
    android:name=".MainActivity"
    android:label="Psycho">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />
    intent-filter>
activity>

在ToolBar中添加一些action按钮,右击res->New->Directory,创建一个menu文件夹,在menu文件夹中创建一个toolbar.xml文件,如下

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/backup"
        android:icon="@mipmap/backup"
        android:title="Backup"
        app:showAsAction="always"
        />
    <item android:id="@+id/delete"
        android:icon="@mipmap/delete"
        android:title="Delete"
        app:showAsAction="ifRoom"/>
    <item android:id="@+id/settings"
        android:icon="@mipmap/seetings"
        android:title="Settings"
        app:showAsAction="never"/>

menu>

通过< item>标签来定义action按钮,android:icon来设置按钮图片,title设置显示文字,app:showAsAction来设置显示位置

showAsAction有三个属性可以选择,always表示永远显示在toolbar中,如果屏幕空间不够则不显示。ifRoom表示屏幕空间足够的情况下显示在toolbar中,不够的话就会显示在菜单中。never表示永远显示在菜单中。

然后在activity中重写onCreateOptionsMenu方法和onOptionsItemSelected方法

public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.toolbar,menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    switch(item.getItemId()){
        case R.id.backup:
            Toast.makeText(this, "You clicked backup", Toast.LENGTH_SHORT).show();
            break;
        case R.id.delete:
            Toast.makeText(this, "You clicked delete", Toast.LENGTH_SHORT).show();
            break;
        case R.id.settings:
            Toast.makeText(this, "You clicked settings", Toast.LENGTH_SHORT).show();
            break;
        default:
    }
    return true;
}

在onCreateOptionsMenu方法中加载了toolbar.xml菜单文件,然后在onOptionsItemSelected方法中处理每个按钮的点击事件

2.滑动菜单

1.DrawerLayout

DrawerLayout是一个布局,在布局中允许放入两个直接子控件,第一个控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容

<androidx.drawerlayout.widget.DrawerLayout 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="match_parent"
    android:id="@+id/drawer_layout">

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

    FrameLayout>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:text="This is menu"
        android:textSize="30sp"
        android:background="#fff"/>
androidx.drawerlayout.widget.DrawerLayout>

第二个直接子控件中的layout_gravity属性是必须的,因为我们要告诉滑动菜单是从左往右滑出,还是从右往左,left表示从左往右,right表示从右往左,start表示根据系统语言判断。

然后我们在ToolBar中最左边加入一个导航按钮,来提示用户滑动菜单。

ActionBar actionBar = getSupportActionBar();
drawerLayout = findViewById(R.id.drawer_layout);
if(actionBar!=null){
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeAsUpIndicator(R.mipmap.menu);
}
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    switch(item.getItemId()){
    	case android.R.id.home:
    		drawerLayout.openDrawer(GravityCompat.START);
    		break;
    }
    return true;
}

2.NavigationView

implementation 'com.android.support:design:28.0.0'
implementation 'de.hdodenhof:circleimageview:2.1.0'

打开app/build.gradle文件,在dependencies闭包中添加上面内容

在使用NavigationView之前,我们还需准备menu和headerLayout,menu是用来在NavigationView显示具体的菜单项,headerLayout是用来在NavigationView显示头布局的

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
    <item android:id="@+id/nav_call"
        android:title="Call"
        android:icon="@mipmap/admin"/>
    <item android:id="@+id/nav_friends"
        android:title="Friends"
        android:icon="@mipmap/friends"/>
    <item android:id="@+id/nav_location"
        android:title="Location"
        android:icon="@mipmap/location_surf"/>
    <item android:id="@+id/nav_mail"
        android:title="Mail"
        android:icon="@mipmap/mail"/>
    <item android:id="@+id/nav_settings"
        android:title="Settings"
        android:icon="@mipmap/interfacesettingline"/>
    group>
menu>

< group>表示一个组,checkableBehavior指定为single表示组中所有的菜单项只能单选

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="180dp"
    android:padding="10dp"
    android:background="?attr/colorPrimary">
    <de.hdodenhof.circleimageview.CircleImageView
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:id="@+id/icon_image"
        android:layout_centerInParent="true"
        android:src="@mipmap/szb"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/mail"
        android:layout_alignParentBottom="true"
        android:text="[email protected]"
        android:textColor="#fff"
        android:textSize="14sp"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/username"
        android:layout_above="@id/mail"
        android:text="宋泽斌"
        android:textColor="#fff"
        android:textSize="14sp"/>
RelativeLayout>

最后,开始使用NacigationView

<androidx.drawerlayout.widget.DrawerLayout 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="match_parent"
    android:id="@+id/drawer_layout">

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

    androidx.coordinatorlayout.widget.CoordinatorLayout>

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

通过app:menu 和 app:headerLayout将我们刚才准备好的menu和headerlayout设置进去,然后在activity中处理点击事件

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 true;
            }
        });

这里我们只为第一个菜单选项设置了点击事件

Material Design(ToolBar,滑动窗口,悬浮按钮和可交互提示)_第1张图片

3.悬浮按钮和可交互提示

1.FloatingActionButton

<androidx.drawerlayout.widget.DrawerLayout 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="match_parent"
    android:id="@+id/drawer_layout">

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

        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="16dp"
            android:src="@mipmap/floatingaction" />
    androidx.coordinatorlayout.widget.CoordinatorLayout>

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

与上次使用DrawerLayout有不同的是,我们这次在第一个子控件使用CoordinatorLayout布局,这个布局可以监听其所有子控件的各种事件,然后自动为我们做出最为合理的响应,所以在之后弹出Snackerbar的时候,FloatingActionButton才不会被遮挡,而是会向上移动。

点击事件处理

FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View view) {
                
      }
});

2.Snackbar

FloatingActionButton fab = findViewById(R.id.fab);
fab.setOnClickListener(this);
public void onClick(View v){
    Snackbar.make(v,"Data deleted",Snackbar.LENGTH_SHORT)
        .setAction("Undo", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(Second.this, "Data restored", Toast.LENGTH_SHORT).show();
            }
        }).show();
}

我们为上面的floatingactionbutton设置的点击事件,会产生一个Snackerbar,用make()方法来创建一个Snackerbar对象,make方法第一个参数传入一个view第二个参数就是Snackerbar显示的内容,接着又调用了setAction方法来设置一个动作。
Material Design(ToolBar,滑动窗口,悬浮按钮和可交互提示)_第2张图片

你可能感兴趣的:(Android,MetrialDesign)