一、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" />
*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的颜色设置为我们提取到的色调
结果:(以本图片为待提取色调的图片,左边为未提取的效果;右图为提取后的效果)
三、举例:滑动菜单
滑动菜单概念:将一些菜单选项隐藏起来,而不是放置在主屏幕上,然后可以通过滑动的方式将菜单显示出来
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、效果如图:
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;
}
});
}
四、举例:悬浮按钮和可交互提示
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();
}
});
}
效果:
4.3 CoordinatorLayout
该布局是一个加强版的FrameLayout,可以监听其所有子控件的各种事情,然后自动帮助我们做出最为合理的响应
实现,只需将FrameLayout变为CoordinatorLayout就行
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
...
</androidx.coordinatorlayout.widget.CoordinatorLayout>
效果如下:
五、卡片式布局
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);
运行效果:
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库提供
/>
效果:
六、举例:下拉刷新
这里主要使用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();
}
....
}
实现效果:
七、举例:可折叠式标题栏
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;
}
}
实现结果:
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主题的查看在如下文件中:
- 2)在values/themes.xml文件中进行修改
<resources xmlns:tools="http://schemas.android.com/tools">
.....
<style name="SoccerActivityTheme" parent="Theme.TestMarterial">
</style>
</resources>
- 3)最后让指定活动使用这个主题
运行结果: