一、Material Design概述
概念:一种材料设计语言,像是VIew的集合,内置多种控件、布局等UI,通过使用可以让Android应用程序的界面趋于统一性
1.1 视图与阴影效果
1、介绍:在Android View的基础上除了X、Y属性还增加了Z属性,该属性对应垂直方向上的高度变化
2、具体:Z值由两部分组成,即Z = elevation + translationZ,其中前者是静态成员,后者则可以在代码中实现动态效果
3、使用:

  • 对于elevation,一般是在XML文件中进行指定,如android:elevation="100dp"
  • 对于translationZ,通过编写代码指定值,如view. translationZ(100)
  • 此外,还可以使用属性动画为视同增加效果,如view.animate(). translationZ(100)

1.2 Tinting和Clipping
Tinting(着色):只需在XML文件中配置即可,其中tint属性用于声明颜色,tintMode给图片蒙上图层,有:add,multiply,screen,src_atop,src_in,src_over这些值,每个值所显示的效果不同

<ImageView
        android:src="@drawable/ic_qq"
        android:layout_width="100dp"
        android:layout_height="100dp"
        tools:ignore="MissingConstraints" />

    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="100dp"
        android:src="@drawable/ic_qq"
        tools:ignore="MissingConstraints"
        app:tint="#3ACDCD" />
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="200dp"
        android:src="@drawable/ic_qq"
        tools:ignore="MissingConstraints"
        android:tintMode="add"
        app:tint="#3ACDCD" />
    <ImageView
        android:layout_width="100dp"
        android:layout_height="100dp"
        app:layout_constraintTop_toTopOf="parent"
        android:layout_marginTop="300dp"
        android:src="@drawable/ic_qq"
        tools:ignore="MissingConstraints"
        android:tintMode="multiply"
        app:tint="#3ACDCD" />

android使用material组件 安卓material_android使用material组件


*Clipping(裁剪):通过裁剪可以改变一个视图的外形

使用步骤:

  • 1、 使用ViewOutlineProvider来修改outline ;
  • 2、再通过setOutlineProvider将outline作用给视

代码:

View textView1 = findViewById(R.id.view1);
        View textView2 = findViewById(R.id.view2);
        ViewOutlineProvider provider = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setRoundRect(0,0,view.getWidth(),view.getHeight(),30);
            }
        };
        ViewOutlineProvider provider1 = new ViewOutlineProvider() {
            @Override
            public void getOutline(View view, Outline outline) {
                outline.setOval(0,0,view.getWidth(),view.getHeight());
            }
        };
        textView1.setOutlineProvider(provider);
        textView2.setOutlineProvider(provider1);

二、举例:Toolbar
2.1 关于Toolbar
1、ActionBar控件:

  • 1)ActionBar主要活动在每一个活动的最顶部
  • 2)ActionBar被限定只能在活动的最顶部
  • 3)ActionBar在AS中的声明位置

2、Toolbar介绍:该控件不仅继承了ActionBar的所有功能,而且以配合其他空间来完成一些Material Design的效果
3、Toolbar的基本使用:

  • 1)在themes.xml主题里更改主题为:
  • 补充:在该theme文件下的各个元素颜色定义的位置
  • 2)Toolbar控件的xml引用:
<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: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="?attr/colorPrimary"
		        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
		        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
		
		</FrameLayout>
分析: xmlns:app="http://schemas.android.com/apk/res-auto":这里指定了一个命名空间,为了满足兼容性。这样Toolbar里的一些属性就可以通过app:attribute来实现了
  • 3)实现:
@Override
		    protected void onCreate(Bundle savedInstanceState) {
		        super.onCreate(savedInstanceState);
		        setContentView(R.layout.activity_main);
		        Toolbar toolbar = findViewById(R.id.toolbar);
		        setSupportActionBar(toolbar);
		    }

4、在Toolbar上添加菜单栏

  • 1)首先在menu文件下创建一个toolbar.xml文件,内容如下:
<?xml version="1.0" encoding="utf-8"?>
	<menu
	    xmlns:app="http://schemas.android.com/apk/res-auto"
	    xmlns:android="http://schemas.android.com/apk/res/android">
	    <item
	        android:id="@+id/add"
	        android:icon="@drawable/add"
	        android:title="添加"
	        app:showAsAction="always"/>
	    <item
	        android:id="@+id/delete"
	        android:icon="@drawable/delete"
	        android:title="删除"
	        app:showAsAction="ifRoom"/>
	    <item
	        android:id="@+id/others"
	        android:icon="@drawable/others"
	        android:title="其他"
	        app:showAsAction="never"/>
	</menu>
1、在开头处同样声明了xmlns:app的命名空间,是为了能够兼容低版本的系统
 2、app:showAsAction指定按钮的显示位置
 3、always表示永远显示在Toolbar中,若屏幕空间不够则不显示
 4、ifRoom表示屏幕空间足够的情况下在Toolbar中,不够就显示在菜单当中
 5、never表示永远显示在菜单当中
  • 2)实现:
public boolean onCreateOptionsMenu(Menu menu){
	        getMenuInflater().inflate(R.menu.toolbar,menu);
	        return true;
	    }
	
	    @Override
	    public boolean onOptionsItemSelected(MenuItem item) {
	        switch (item.getItemId()){
	            case R.id.add:
	                Toast.makeText(this,"添加",Toast.LENGTH_SHORT).show();
	                break;
	            case R.id.delete:
	                Toast.makeText(this,"删除",Toast.LENGTH_SHORT).show();
	                break;
	            case R.id.others:
	                Toast.makeText(this,"其他",Toast.LENGTH_SHORT).show();
	                break;
	            default:
	                break;
	        }
	        return true;
	    }

5、可以利用Toolbar上修改标题栏上显示的内容(添加菜单为例)
2.2 Palette
1、概念:Palette一般用来提取颜色,从而让主题能够动态适应当前界面的色调。
2、Android内置了几种提取色调的种类:

  • Vibrant
  • Vibrant dark
  • Vibrant light
  • Muted
  • Muted dark
  • Muted light

3、具体实现代码:
首先需要导入依赖:implementation 'com.android.support:palette-v7:23.0.1' 然后具体代码:

用7etteAsyncListener() {
            @Override
            public void onGenerated(@Nullable Palette palette) {
                Palette.Swatch swatch = palette.getVibrantSwatch();
                getSupportActionBar().setBackgroundDrawable(new ColorDrawable(swatch.getRgb()));
            }
        });
1)首先将待提色的图片存入到Bitmap的对象中
	2)然后将Bitmap对象传入到Palette中,后者调用generate()方法即可
	3)在onGenerated()方法中回调得到图片的色调,这里通过 palette.getVibrantSwatch()调用 选择提取色调的颜色,同时还有getMutedSwatch()、getDarkVibrantSwatch()等方法供调用
	4)并将Toolbar的颜色设置为我们提取到的色调

结果:(以本图片为待提取色调的图片,左边为未提取的效果;右图为提取后的效果)

android使用material组件 安卓material_xml_02

三、举例:滑动菜单
滑动菜单概念:将一些菜单选项隐藏起来,而不是放置在主屏幕上,然后可以通过滑动的方式将菜单显示出来
3.1 DrawerLayout
DrawerLayout:一种布局,在布局中允许放入两个直接的子控件:①第一个子控件是主屏幕中显示的内容;②第二个子控件是滑动菜单中显示的内容。
实现方法:
1、xml文件下的布局:

<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/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    tools:context=".MainActivity">
    <FrameLayout
       ....
    </FrameLayout>
    <TextView
        android:text="Menu"
        android:layout_gravity="start"
        android:background="#fff"
        android:textSize="25sp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
</androidx.drawerlayout.widget.DrawerLayout>
1、在该布局下有两个子控件,第一个就是Toolbar,第二个是一个TextView
	2、在第二个子控件中android:layout_gravity是必须指定的,其中的参数:left表示滑动菜单在左边;right表示在右边;start表示根据系统语言判断

2、实现点击导航栏弹出滑动菜单

public class MainActivity extends AppCompatActivity {
    private DrawerLayout drawerLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
       	...
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        drawerLayout = findViewById(R.id.drawer_layout);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setHomeAsUpIndicator(R.drawable.menu);
        }
    }
    ...
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                drawerLayout.openDrawer(GravityCompat.START);
                break;
            ....
            default:
                break;
        }
        return true;
    }
}
1、首先获取了DrawerLayout的一个实例
2、接着通过ActionBar(实际上是通过Toolbar实现的) 的setDisplayHomeAsUpEnabled()方法让导航按钮显示出来
3、调用setHomeAsUpIndicator()方法设置一个导航按钮图标
4、通过一个id:android.R.id.home,调用DrawerLayout的openDrawer()方法将滑动菜单展示出来

3、效果如图:

android使用material组件 安卓material_android使用material组件_03

3.2 NavigantionView 在滑动菜单中实现其他功能
1、首先导入Design Support库

implementation 'com.android.support:design:24.2.1'

2、然后要自己搞两个文件,nav_menu.xml和nav_header.xml文件;

<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <group android:checkableBehavior="single">
        <item
            android:id="@+id/call"
            android:icon="@drawable/telephonw"
            android:title="电话"/>
        <item
            android:id="@+id/friend"
            android:icon="@drawable/friend"
            android:title="好友"/>
        <item
            android:id="@+id/location"
            android:icon="@drawable/location"
            android:title="位置"/>
        <item
            android:id="@+id/mail"
            android:icon="@drawable/mail"
            android:title="邮件"/>
        <item
            android:id="@+id/task"
            android:icon="@drawable/task"
            android:title="任务"/>
    </group>
</menu>
1、其中:group标签表示一个组,checkableBehavior指定为single表示组中所有的菜单只能单选
	2、title属性制定菜单项显示的文字
<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">
    <ImageView
        android:id="@+id/head"
        android:src="@drawable/head"
        android:layout_width="70dp"
        android:layout_height="70dp"
        android:layout_centerInParent="true"/>
    <TextView
        android:id="@+id/name"
        android:text="Cristiano"
        android:textSize="20sp"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <TextView
        android:id="@+id/tele"
        android:text="123456789"
        android:textSize="20sp"
        android:layout_above="@id/name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

3、然后修改DrawerLayout里的布局

<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/drawer_layout"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    tools:context=".MainActivity">
    <FrameLayout
       .....
    </FrameLayout>
    <com.google.android.material.navigation.NavigationView
        android:id="@+id/nav_view"
        android:layout_gravity="start"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:menu="@menu/nav_menu"//菜单选项引用
        app:headerLayout="@layout/nav_header"//菜单头部头部/>
</androidx.drawerlayout.widget.DrawerLayout>

4、实现:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        NavigationView navigationView = findViewById(R.id.nav_view);
        ...
        navigationView.setCheckedItem(R.id.call);//设置默认选中项
		//设置一个菜单项选中事件的监听器
        navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                drawerLayout.closeDrawers();//关闭滑动菜单栏
                return true;
            }
        });
    }

android使用material组件 安卓material_android_04


四、举例:悬浮按钮和可交互提示

4.1 FloatingActionButton

概念:该控件可以实现悬浮按钮的效果。

实现方式:

<FrameLayout
       	....
        <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"
            //end的工作原理和滑动菜单的start一样,根据系统语言来放置在左边还是右边
            android:layout_margin="16dp"
            app:elevation="8dp"//该属性用于给控件指定一个高度值
         	/>
    </FrameLayout>

实现点击事件:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(MainActivity.this,"FAB ????",Toast.LENGTH_SHORT).show();
            }
        });
    }

4.2 Snackbar
1、Toast与Snackbar的区别:

  • Toast:告诉用户现在发生了什么事情,同时用户只能被动接受这个事情
  • Snackbar:允许在提示中加入一个可交互按钮,当用户点击按钮时可以执行一些额外的逻辑操作
    2、使用方式:
@Override
    protected void onCreate(Bundle savedInstanceState) {
        ...
        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
            	//make方法中:第二个参数是Snackbar显示的内容
                Snackbar.make(view,"Deleted",Snackbar.LENGTH_SHORT).setAction("Undo", new View.OnClickListener() {
                            @Override
                            public void onClick(View view) {
                                Toast.makeText(MainActivity.this,"restored",Toast.LENGTH_SHORT).show();
                            }
                        }).show();
            }
        });
    }

效果:

android使用material组件 安卓material_xml_05


4.3 CoordinatorLayout

该布局是一个加强版的FrameLayout,可以监听其所有子控件的各种事情,然后自动帮助我们做出最为合理的响应

实现,只需将FrameLayout变为CoordinatorLayout就行

<androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">
       	...
    </androidx.coordinatorlayout.widget.CoordinatorLayout>

效果如下:

android使用material组件 安卓material_android使用material组件_06


五、卡片式布局

5.1 CardView

该控件是用于实现卡片式布局效果的重要控件

1、关于卡片式布局的依赖

implementation 'com.android.support:cardview-v7:24.2.1'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.github.bumptech.glide:glide:3.7.0'//这是一个Glide库的依赖,这个库是一个功能强大的图片加载库

2、通过使用一个RecyclerView来展示卡片式布局效果

  • 1)对于每个元素使用卡片式布局
<androidx.cardview.widget.CardView
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="5dp"
    app:cardCornerRadius="4dp">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/image"
            android:scaleType="centerCrop"//这个属性用于指定图片的缩放模式,centerCrop指明让图片保持原有的比例填满ImageView
            android:layout_width="200dp"
            android:layout_height="100dp"/>
        <TextView
            android:id="@+id/name"
            android:layout_gravity="center_horizontal"
            android:layout_margin="5dp"
            android:textSize="16sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </LinearLayout>
</androidx.cardview.widget.CardView>
  • 2)使用Glide加载图片
public class SoccerAdapter extends RecyclerView.Adapter<SoccerAdapter.ViewHolder>{
	......
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        Soccer soccer = soccerList.get(position);
        holder.soccerText.setText(soccer.getName());
        Glide.with(context).load(soccer.getImageId()).into(holder.soccerImage);
        //调用with()方法传入一个Context、Activity或Fragment参数
        //调用load()方法加载图片,传入的参数可以使URL地址或本地路径或资源id
        //用Glide加载图片可以不用考虑到内存溢出、像素丢帧的问题
    }
	....
}
  • 3)实现网格布局:
GridLayoutManager manager = new GridLayoutManager(this,2);

运行效果:

android使用material组件 安卓material_android_07


5.2 AppBarLayout

现在存在上述问题,卡片式布局把Toolbar给遮挡住了。我们通过使用AppBarLayout可以解决这类问题,这是 一个垂直方向的LinearLayout,它在内部做了很多滚动事件的封装,可以解决上述问题中遮住Toolbar控件的问题。

使用方法:

1、将Toolbar嵌套到AppbarLayout中;2、给RecyclerView指定一个布局行为

<com.google.android.material.appbar.AppBarLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="?attr/colorPrimary"
                android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
                app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
                app:layout_scrollFlags="scroll|enterAlways|snap"
				//app:layout_scrollFlags属性指定滚动效果,其中:
				//scroll表示RecyclerView向上滚动时,Toolbar跟着一起向上滚动并隐藏
				//enterAlways表示RecyclerView向下滚动时,Toolbar跟着一起向下滚动并重新显示
				//snap表示当Toolbar还没有完全隐藏或显示时,会根据当前滚动的距离,自动选择是显示还是隐藏
		/>
        </com.google.android.material.appbar.AppBarLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"//该字符串是由Design Support库提供
            />

效果:

android使用material组件 安卓material_android_08


六、举例:下拉刷新

这里主要使用SwipeRefreshLayout这一个类来实现下来刷新,把要实现下来刷新功能的控件放置到SwipeRefreshLayout当中即可下来刷新

1、先要将RecyclerView放到SwipeRefreshLayout当中

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
            android:id="@+id/swipe_refresh"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_behavior="@string/appbar_scrolling_view_behavior">
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recycler_view"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
        </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

2、代码实现:

public class MainActivity extends AppCompatActivity {
	.....
    private SwipeRefreshLayout swipeRefreshLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        .....
        swipeRefreshLayout = findViewById(R.id.swipe_refresh);
        swipeRefreshLayout.setColorSchemeResources(R.color.black);
        //setColorSchemeResources()方法设置下拉刷新进度条颜色
        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                refresh();//设置一个监听器,表示刷新时要实现的操作
            }
        });
    }
    private void refresh(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try{
                    Thread.sleep(2000);//线程沉睡2秒以便于看得到刷新效果
                }catch (Exception e){
                    e.printStackTrace();
                }
                runOnUiThread(new Runnable() {//切换回主线程
                    @Override
                    public void run() {
                        init();
                        soccerAdapter.notifyDataSetChanged();//通知数据发生变化
                        swipeRefreshLayout.setRefreshing(false);//用于表示刷新事件结束,并隐藏刷新进度条
                    }
                });
            }
        }).start();
    }
    ....
}

实现效果:

android使用material组件 安卓material_android使用material组件_09


七、举例:可折叠式标题栏

7.1 CollapsingToolbarLayout

1、该布局是一个作用于Toolbar基础之上的布局,可以让Toolbar的效果变得更加丰富

2、该布局只能作为AppBarLayout的直接子布局来使用,且APPBarLayout必须是CoordinatorLayout的子布局

3、具体使用:

  • 1)创建一个活动,实现最外层CoordinatorLayout布局
<androidx.coordinatorlayout.widget.CoordinatorLayout
    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"
    tools:context=".SoccerActivity">
    
</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 2)实现AppBarLayout布局
<androidx.coordinatorlayout.widget.CoordinatorLayout
    .....>

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBar"
        android:layout_width="match_parent"
        android:layout_height="250dp">
    </com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 3)嵌套CollapsingToolbarLayout布局
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ....>
    <com.google.android.material.appbar.AppBarLayout
      	.....
        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:contentScrim="?attr/colorPrimary"//用于指定CollapsingToolbarLayout在区域折叠状态以及折叠之后的背景色
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            //app:layout_scrollFlags属性:scroll表示CollapsingToolbarLayout会随着内容详情的滚动一起滚动;exitUntilCollapsed表示当CollapsingToolbarLayout随着滚动完成折叠之后就会保留在界面上
            >
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 4)为标题栏定义内容
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ....>
    <com.google.android.material.appbar.AppBarLayout
        .....>
        <com.google.android.material.appbar.CollapsingToolbarLayout
            .....>
            <ImageView
                android:id="@+id/image1"
                android:scaleType="centerCrop"
                app:layout_collapseMode="parallax"
                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"
                app:layout_collapseMode="pin"/>
       //app:layout_collapseMode用于指定当前控件在CollapsingToolbarLayout折叠过程中的折叠模式:pin不爱事故在折叠过程中位置适中保持不变;parallax表示在折叠过程中产生一定的错位偏移         
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 5)为内容栏添加布局
<androidx.coordinatorlayout.widget.CoordinatorLayout
    .....>
    ......
    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior">
        <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>
NestedScrollView是ScrollView的一个升级版
  • 6)为内容栏添加控件
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout
    ......>
    ......
    <androidx.core.widget.NestedScrollView
        .....>
        <LinearLayout
            .....>
            <androidx.cardview.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_margin="15dp"
                android:layout_marginTop="35dp"
                app:cardCornerRadius="4dp">
                <TextView
                    android:id="@+id/text1"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_margin="10dp"/>
            </androidx.cardview.widget.CardView>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 7)加入悬浮按钮
<androidx.coordinatorlayout.widget.CoordinatorLayout
    .....>
	.....
    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="16dp"
        app:layout_anchor="@id/appBar"//该属性制定了一个锚点,现在指定为AppBarLayout,表示该按钮会出现在标题栏的区域内
        app:layout_anchorGravity="bottom|end"/>//根据锚点位置,将按钮定义在标题栏右下角
</androidx.coordinatorlayout.widget.CoordinatorLayout>
  • 8)具体实现:
public class SoccerActivity extends AppCompatActivity {
    public static final String Soccer_Name = "soccer_name";
    public static final String Soccer_Image = "soccer_image";
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_soccer);
        Intent intent = getIntent();
        String name = intent.getStringExtra(Soccer_Name);
        int image = intent.getIntExtra(Soccer_Image,0);
		//获取图片和名字实例
		
        Toolbar toolbar = findViewById(R.id.toolbar);
        CollapsingToolbarLayout collapsingToolbarLayout = findViewById(R.id.collapsing_toolbar);
        ImageView imageView = findViewById(R.id.image1);
        TextView textView = findViewById(R.id.text1);
		//声明控件
		
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if(actionBar != null){
            actionBar.setDisplayHomeAsUpEnabled(true);
        }
		//实现Toolbar的代替,并且将活动中隐藏的返回按钮显示出来

        collapsingToolbarLayout.setTitle(name);
        Glide.with(this).load(image).into(imageView);
		//标题栏的图片和名字设定

        String content = Content(name);
        textView.setText(content);
        //内容栏内容
    }
    private String Content(String name){
        StringBuilder stringBuilder = new StringBuilder();
        for(int i=0;i<500;i++){
            stringBuilder.append(name);
        }
        return stringBuilder.toString();
    }

    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        switch (item.getItemId()){
            case android.R.id.home:
                finish();//为标题栏的返回按钮定义事件
                return true;
        }
        return super.onOptionsItemSelected(item);
    }
}
  • 9)对于前一个活动设置item点击事件
public class SoccerAdapter extends RecyclerView.Adapter<SoccerAdapter.ViewHolder>{
    private Context context;
    private List<Soccer> soccerList;
    public SoccerAdapter(List<Soccer> soccerList){
        this.soccerList = soccerList;
    }
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (context == null){
            context = parent.getContext();
        }
        View view = LayoutInflater.from(context).inflate(R.layout.soccer_item,parent,false);
        final ViewHolder holder = new ViewHolder(view);
        holder.cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition();
                Soccer soccer = soccerList.get(position);
                Intent intent = new Intent(context,SoccerActivity.class);
                intent.putExtra(SoccerActivity.Soccer_Name,soccer.getName());
                intent.putExtra(SoccerActivity.Soccer_Image,soccer.getImageId());
                context.startActivity(intent);
            }
        });
        return holder;
    }
}

实现结果:

android使用material组件 安卓material_xml_10


android使用material组件 安卓material_ide_11


android使用material组件 安卓material_xml_12

7.2 充分利用系统状态栏空间
将背景图和系统状态栏融合,使用 android:fitsSystemWindows="true"即可

<androidx.coordinatorlayout.widget.CoordinatorLayout
    ...
    android:fitsSystemWindows="true">
    <com.google.android.material.appbar.AppBarLayout
        ...
        android:fitsSystemWindows="true">
        <com.google.android.material.appbar.CollapsingToolbarLayout
            ...
            android:fitsSystemWindows="true">
            <ImageView
                ...
                android:fitsSystemWindows="true"/>
            ...
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>
 	.....
</androidx.coordinatorlayout.widget.CoordinatorLayout>

此外,还需在程序中的主题中将状态栏颜色制定成透明色,具体步骤:

  • 1)res目录 > New > Directory ,创建values-v21目录,然后在此目录下创建themes.xml文件
<resources>
    <style name="SoccerActivityTheme" parent="Theme.TestMarterial">
        <item name="android:statusBarColor">
            @android:color/transparent//指定为透明色
        </item>
    </style>
</resources>

定义了一个名为SoccerActivityTheme的主题,它的parent主题的查看在如下文件中:

android使用material组件 安卓material_ide_13

  • 2)在values/themes.xml文件中进行修改
<resources xmlns:tools="http://schemas.android.com/tools">
   	.....
    <style name="SoccerActivityTheme" parent="Theme.TestMarterial">
    </style>
</resources>
  • 3)最后让指定活动使用这个主题

    运行结果:


android使用material组件 安卓material_xml_14