Android学习-Material Design

谷歌工程师们设计的界面设计语言。

Toolbar

活动最顶部的那个标题栏就是ActionBar。

ActionBar由于设计的原因,被限定只能位于活动的顶部,从而不能实现一些效果,因此官方现在已经不建议使用ActionBar了。那我们学习Toolbar。

Toolbar的强大之处在于,它不仅继承了ActionBar的所有功能,而且灵活性很高,可以配合其他控件来完成一些Material Design的效果。

首先需要知道,任何一个新建的项目,默认都是会显示ActionBar的,ActionBar是根据项目中指定的主题来显示的,打开AndroidManifest.xml文件看一下,如图:

在这里插入图片描述
可以看到android:theme属性指定了一个AppTheme的主题。那么这个AppTheme又是在哪里定义的呢?打开res/values/styles.xml文件,代码如下:
在这里插入图片描述
这里定了一个叫AppTheme的主题,然后指定他的parent主题是Theme.AppCompat.Light.DarkActioinBar。这个DarkActioinBar是一个深色的ActionBar主题,我们之前所有的项目中自带的ActionBar就是因为制定了这个主题才出现的。

而我们现在准备使用Toolbar来替代ActionBar,因此需要制定一个不带ActionBar的主题,通常有Theme.AppCompat.NoActioinBar和Theme.AppCompat.Light.NoActioinBar这两种主题可选。
其中前者表示神色主题,它会将界面的主题颜色设为深色,陪衬颜色设为单色。而后者表示淡色主题,它会将界面的主体颜色射程淡色,陪衬颜色设为深色。

选用淡色主题,如下:
在这里插入图片描述
然后观察AppTheme中的属性重写,这里重写了colorPrimary,colorPrimaryDark和colorAccent这三个属性的颜色。那么这三个属性分别代表着什么颜色呢,AS里可以看。

除了上述三个属性之外,我们还可以通过textColorPriamary、windowBackground和navigationBarColor等属性来控制更多位置的颜色。不过维度colorAccent这个属性比较难理解,它不只是用来指定这样一个按钮的颜色,而是更多表达了一个强调的意思,比如一些空间的选中状态也会使用colorAccent的颜色。

现在我们已经将ActionBar隐藏起来了

第二种方式: 在 MainActivity 类中的onCreate方法下添加一行代码: (Activity 继承自
AppCompatActivity 时) getSupportActionBar().hide();//这种方式默认式亮色主题 或者
(Activity 继承自 Activity 时) getActionBar().hide();

接下来使用Toolbar,如图:
在这里插入图片描述
第二行xmln:app制定了一个新的命名空间。
思考一下,正是由于每个布局文件都会使用xmlns:android来指定一个命名空间,所以我们才能一直使用android:id、android:layout_width等写法。
那么这里制定了xmlns:app,也就是说现在可以使用app:attribute这样的写法了。

但是为什么这里要指定一个xmlns:app的命名空间呢?这是由于Material Design是在Android5.0系统中才出现的。而很多的Material属性在5.0之前的系统中并不存在,那么为了能够兼容之前的老系统,我们就不能使用android:attribute这样的写法了,而是应该使用app:attribute。

接下来定义了一个Toolbar控件,这个控件是由appcompat-v7库提供的。这里我们给Toolbar指定了一个id,将它的宽度设置为match_parent,高度设置为actionBar的高度,背景色设置为colorPrimary。

由于刚才在styles.xml中将程序的主题指定成了淡色主题,因此Toolbar现在也是淡色主题,而Toolbar上面的各种元素就会自动使用深色系,这是为了和主体颜色区别开。但是这个效果看起来就很差,之前使用ActionBar时文字都是白色的,现在变成黑色会很难看。

那么为了能让Toolbar单独使用深色主题,这里我们使用android:theme属性,将Toolbar的主题指定成了ThemeOverlay.AppCompat.Dark.ActionBar。
但是这样指定完了就会有新的问题,如果Toolbar中由菜单按钮,那么弹出的菜单项也会变成深色主题,又难看了。

于是这里使用了app:popupTheme属性单独将弹出的菜单项指定成了淡色主题。之所以使用app:popupTheme,是因为popupTheme这个属性实在Android5.0系统中新增的,我们使用app:popupTheme的话就可以兼容Android5.0以下的系统了。

接下来修改活动,代码如下:
在这里插入图片描述
在这里插入图片描述
先find到Toolbar的实例,然后调用setSupportActionBar的方法并将Toolbar的实例传入,这样我们就做到既使用了Toolbar,又让它的外观与功能都和ActionBar一致了。

接下来学习一些Toolbar比较常用的功能,比如修改标题栏上显示的文字内容。

这段文字实在AndroidManifest.xml中指定的,如下:

在这里插入图片描述
在这里插入图片描述
这里给activity增加了一个android:label属性,用于指定在Toobar中显示的文字内容,如果没有指定的话,会默认使用application中指定的label内容,也就是我们的应用名称。

不过只有一个标题的Toolbar看起来太单调了,我们还可以再添加一些action按钮来让Toolbar更加丰富一些,这里准备几张图片来作为按钮的图标,把它们放在drawable-xxhdpi目录下。在这里插入图片描述

然后右击
在这里插入图片描述
在这里插入图片描述
item来定义action按钮,titile为按钮文字。
app:showAsAction来指定按钮的显示位置,之所以在这里再次使用app命名空间,同样是为了能够兼容低版本的系统。
showAsAction主要有以下几种值可以选:
always表示永远显示在Toolbar中,如果屏幕空间不够则不显示
ifRoom表示屏幕空间足够的情况下显示在Toolbar中,不够的话就显示在菜单当中;
never表示永远显示在菜单中。
注意,Toolbar中的action按钮只会显示图标,菜单中的action按钮只会显示文字。

修改活动中的代码:
在这里插入图片描述
在这里插入图片描述
在onCreateOptionsMenu方法中加载了toolbar.xml这个菜单文件,然后在onOptionsItemSelected方法中处理各个按钮的点击事件。

实例如图:
在这里插入图片描述
现在Toolbar上面显示了两个action按钮,这是因为Backup按钮指定的显示位置是always,Delete显示位置是ifRoom,现在屏幕空间很足,因此两个按钮都会显示。

另外一个Settings按钮由于指定的位置是never,所以不会显示在Toolbar中,点击一下最右边的菜单按钮来展开菜单项,就可以找到Settings按钮了。

另外这个action按钮都是可以响应点击事件的。

滑动菜单

DrawerLayout

所谓的滑动菜单就是将一些菜单选项隐藏起来,而不是放置在主屏幕上,然后可以通过滑动的方式将菜单显示出来。这种方式既节省了屏幕空间,又实现了非常好的动画效果。

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

对activity_main修改:
在这里插入图片描述
在这里插入图片描述
这里最外层的空间使用了DrawerLayout,这个控件是由support-v4库提供的。DrawerLayout中放置了两个直接子控件。
第一个子控件是FrameLayout,用于作为主屏幕中显示的内容,当然里面还有我们刚刚定义的Toolbar。
第二个子控件这里使用了一个Textview,用于作为滑动菜单中显示的内容,其实使用什么都可以,DrawerLayout并没有限制,只能使用固定的控件。

但第二个子控件有一点需要注意,layout_gravity这个属性必须指定的,因为我们需要告诉DrawerLayout滑动菜单是在屏幕左边还是右边,指定left表示滑动菜单在左边。
这里指定了start、,表示会根据系统语言进行判断,如果系统语言是从左往右的,比如英语,汉语,滑动菜单就在左边,如果是从右往左例如阿拉伯语,滑动菜单就在右边。

实例如图:
在这里插入图片描述
然后向左滑动菜单,或者点击一下菜单以外的区域,都可以让滑动菜单关闭,从而回到主界面。伟伦是展示还是隐藏滑动菜单,都是由非常流畅的动画过渡。

不过现在的滑动菜单还有点问题,因为只有在屏幕的左侧边缘进行拖动时才能将菜单拖出来,而很多用户可能根本就不知道这个功能,那么该怎么提醒他们呢?

Material Desigh建议的做法是在Toolbar的最左边加入一个导航按钮,点击了按钮也会将滑动菜单的内容展示出来。

下面开始实现这个功能,首先准备一张导航按钮的图片ic_menu.png,将它放在了drawable-xxhdpi目录下。然后修改活动中的代码:

在这里插入图片描述
先find到DrawerLayout的实例,然后调用getSupportActionBar方法得到了ActionBar的实例,虽然这个ActionBar的具体实现是由Toolbar来完成的。

接着调用ActionBar的setDisplayHomeAsUpEnabled方法让盗汗按钮显示出来,又调用了setHomeAsUpIndicator方法来设置一个导航按钮图标。
实际上,Toolbar最左侧这个按钮叫做HomeAsUp按钮,他的默认图标是一个返回的箭头,含义是返回上一个活动。

我们在这里将它默认的样式和作用都进行了修改。

接下来在onOptionsItemSelected方法中对HomeAsUp按钮的点击事件进行处理,HomeAsUp按钮的id用于都是android.R.id.home。
然后调用DrawerLayout的openDrawer方法将滑动菜单展示出来,注意openDrawer方法要求传入一个Gravity参数,为了保证这里的行为和XML中定义的一致,传入GravityCompat.START.

运行后如图:

在这里插入图片描述

NavigationView

NavigationView

我们可以用刚刚的方法在滑动菜单页面指定任意的布局,不过谷歌给我们提供了一种更好的方法,使用NavigationView。它是Design Support库中提供的一个控件,它不仅是严格按照Material Design的要求来设计的,而且还可以将滑动菜单页面的实现变得非常简单。

首先这个控件是由Design Support库提供的,那么我们就需要将这个库引入到项目中才行。

打开app/build.gradle文件,在denpendencies闭包中添加如下内容:
在这里插入图片描述
第一行就是Design Support库,第二行是一个开源项目CircleImageView,它可以用来轻松实现图片圆形化的功能。

在开始使用NavigationView之前,还需要提前准备好两个东西:menu和headerLayout。
menu是用来在NavigationView中显示具体的菜单项的,headerLayout是用来在NavigationView中显示头部布局的。

现在准备menu,这里是找了几张图片来作为按钮的图标,并把它们放在drawable-xxhdpi目录下。在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在menu中嵌套了一个group标签,然后将group的checkableBehavior属性指定为single。group表示一个组,che’ckableBehavior指定为single表示组中的所有菜单项只能单选。

菜单项中定义了五个item。

接下来准备headerLayout,这是一个可以随意定制的布局,简单起见,就在headerLayout中防止头像、用户名和邮箱地址这三项内容。

准备头像,又准备一张图片放入刚刚的目录下。一会把它圆形化。

然后在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
CircleImageView是一个用于将图片圆形化的控件,它的用法非常简单,基本和ImageView完全一样。另外两个textview显示用户名和邮箱。

现在menu和headerLayout都准备好了,开始使用NavigationView,修改acitivity_main.xml中的代码,如下:
在这里插入图片描述
在这里插入图片描述
这里将之前的textview换成了NavigationView,这样滑动菜单中的呢日哦那个也就变成NavigationView了。

这里又通过app:menu和app:headerLayout属性将刚准备好的menu和headerLayout设置进去。NavigationView定义完成。

接下来处理菜单项中的点击事件,修改MainActivity:

在这里插入图片描述

先获取了NavigationView的实例,然后调用它的setCheckedItem方法将Call菜单项设置为默认选项。
接着调用了setNavigationIemSelectedListener方法来设置一个菜单选项中事件的监听器,当用户点击了任意菜单项时,就会回调到onNavigationItemSelected方法中。我们可以在这个方法中写相应的逻辑处理,不过这里没有附加任何逻辑,只是调用了DrawerLayout的closeDrawers方法将滑动菜单关闭。

实例如图:
在这里插入图片描述

悬浮按钮和可交互提示

在这里插入图片描述

关于提示工具,之前我们一直都是使用Toast,但是Toast只能用于告知用户某某事情已经发生了,用户却不能对此做出任何的相应,今天在这一方面进行扩展。

FloatingActionButton

FloatingActionButton是Design Support库中提供的一个控件,这个控件可以帮助我们轻松实现悬浮按钮的效果。它会默认使用colorAccent来作为按钮的颜色,我们还可以通过给按钮指定一个图标来表明这个按钮的作用是什么。

下面来具体实现,首先仍然需要准备好一个图标。然后修改activity_main.xml中的代码:
在这里插入图片描述
gravity属性指定将这个控件放置于屏幕的右下角,其中end的工作原理和之前的start是一样的,即如果系统语言是从左往右的,那么end就表示在右边,如果系统语言是从右往左的,那么end就表示在左边。然后通过layout_margin属性给控件的四周留点边距,src设置图标。

我们还可以指定它的悬浮高度,如图:
在这里插入图片描述

添加点击事件:

在这里插入图片描述

Snackbar

Design Support库提供的更加先进的提示工具。
首先它不是Toast的替代品,它们两者有着不同的应用场景。
Toast的作用是告诉用户现在发生了什么事情,但同时用户只能被动接受这个事情,因为没有办法可以让用户进行选择。
而Snackbar在这方面进行了扩展。
打个比方,如果我们再执行删除操作时天出一个Toast提示,那么用户要是误删了某个重要数据一定很难过,但是如果增加一个Undo按钮,就相当于给用户提供了以中弥补措施,提升用户体验。

它和Toast用户基本相似,只不过可以额外增加一个按钮的点击事件,修改MainActivity中的代码,如下:
在这里插入图片描述
这里调用了Snackbar的make方法来创建一个Snackbar对象,make方法的第一个参数需要传入一个view,只要是当前界面布局的任意一个view都可以,Snackbar会使用这个view来自动查找最外层的布局用于展示Snackbar。(不懂。。)
第二个参数就是Snackbar中显示的内容
第三个参数是Snackbar显示的时长。

接着又调用了一个setAction方法来设置一个动作,从而让Snackbar不仅仅是一个提示,还可以和用户进行交互。

最后用show方法让Snackbar显示出来。

但是有一个bug,Snackbar会遮挡住悬浮按钮。
需要借助CoordinatorLayout就可以解决。

CoordinatorLayout

可以说是一个加强版的FrameLayout,这个布局也是由Design Support库提供的。
它在普通情况下的作用和FrameLayout基本一致,不过既然是Design Support库中提供的布局,那么一定就有一些Material Design的魔力了。

事实上,CoordinatorLayout可以监听其所有子控件的各种事件,然后自动帮我们做出最为合理的响应。
举个简单的例子,刚刚弹出的Snackbar提示将悬浮按钮遮挡住了,而如果我们能让CoordinatorLayout监听到Snackbar的弹出事件,那么它会自动将内部的FloatingActionButton向上偏移,从而确保不会被Snackbar遮挡,如图:

在这里插入图片描述
FrameLayout替换为CoordinatorLayout。

回过头来思考一下,CoordinatorLayout可以监听其所有子控件的各种事件,但是Snackbar并不是CoordinatorLayout的子控件,为什么它可以被监听到呢?

其实道理很简单,在Snackbar的make方法中传入的第一个参数,这个参数就是来指定Snackbar是基于哪个view来触发的,刚才我们传入的是FloatingACtionButton本身,而FloatingACtionButton是CoordinatorLayout的子控件,因此这个时间就可以被监听到了。

卡片式布局

在这里插入图片描述
在这里插入图片描述

CardView
CardView是用于实现卡片式布局的重要空间,由appcompat-v7提供。实际上CardView也是一个FrameLayout,只是额外提供了圆角和阴影等效果,看上去会有立体的感觉。

先看下CardView的基本用法,如下:
在这里插入图片描述
这里定义了一个CardView布局,我们还可以通过app:cardCornerRadius属性指定卡片圆角的弧度,数值越大弧度越大。
还可以通过app:elevation指定卡片的高度,高度值越大,投影范围越大,但是投影效果越淡,高度值越小,投影范围越小,但是投影效果越浓,这一点和FrameActionButton是一致的。

然后在CardView布局中放置了一个Textview,然后它就会显示在一张卡片当中。

但显然不可能在如此宽阔的一块空白区域之防止了一张卡片,为了充分利用屏幕,可以使用RecyclerView来填充MaterialTest项目的主界面部分,实现一个高配的水果列表效果。

需要用到RecyclerView、CardView这几个控件,因此必须在app/build.gradle文件中声明这些库的依赖才行:
在这里插入图片描述
在这里插入图片描述
声明的最后一行,这里添加了一个Glide库的依赖。Glide是一个超级强大的图片加载库,它不仅可以加载本地图片,还可以加载网络图片、GIF、本地视频。
最终稿要的是它的用法非常简单,只需要一行代码就可以实现图片加载功能,因此这里使用它来加载水果图片。

代码实现,修改activity_main.xml中的代码:
在这里插入图片描述
接着定义一个实体类,如下:
在这里插入图片描述
在这里插入图片描述
然后需要为RecyclerView的子项指定一个自定义的布局,在layout目录下新建fruit_item.xml,代码如下:
在这里插入图片描述
这里使用了CardView来作为子项的最外层布局,从而使得RecycylerView中每一个元素都是在卡片当中。
CardView由于是一个FrameLayout,因此他没有什么方便的定位方式,这里只好在CardView中再嵌套一个LinerLayout,然后再LinerLayout放置具体的内容。

内容部分,为了让所有图片都能填充整个ImageView,这里使用了centerCrop模式,它可以让图片保持原有比例填充满ImageView,并将超出屏幕的部分裁剪掉。

接下来为RecycylerView准备一个适配器,新建FruiAdapter类,让这个适配器继承自RecyclerView.Adapter,并将泛型指定为FruitAdapter.ViewHolder,代码如下:
在这里插入图片描述
在这里插入图片描述
在onBindViewHolder方法中使用了Glide来加载水果图片。

手续爱你调用Glide.with方法并传入一个Context、Activity或Fragment参数,然后调用load方法去加载图片,可以是一个URL地址,也可以是一个本地路径,或者是一个资源id,最后调用into方法将图片设置到某一个具体的ImageView中就可以了。

为什么要使用Glide而不是传统的设置图片方式呢?因为书中找的图片像素都很高,如果不进行压缩直接展示很容易引起内存一处。而使用Glide就不需要担心,它内部有很多复杂的逻辑操作,其中包括了图片的压缩,安心按照Glide的标准用法去加载图片就可以了。

适配器准备好之后修改MainActivity中的代码,如下:

在这里插入图片描述
在这里插入图片描述
这里使用了GridLayoutManager这种布局方式。

它的构造函数接受两个参数,第一个是Context,第二个是列数,这里希望每一行中会有两列数据
实例:
在这里插入图片描述
Toolbar被RecyclerView给挡住了。
需要借助另一个工具AppBarLayout

AppBarLayout

首先分析为什么会挡住,因为RecyclerView和Toolbar都是放置在CoordinatorLayout中的,而它是一个加强版的FrameLayout,那么FrameLayout中的所有控件在不进行明确定位的情况下,默认都会摆放在布局的左上角,从而也就产生了遮挡的现象。

应该让RecyclerView向下偏移一个Toolbar的高度。

AppBarLayout实际上是一个垂直方向的LinearLayout,它在内部做了很多滚动事件的封装,并应用了一些Material Design的设计理念。

解决覆盖问题:
第一步将Toolbar潜逃到AppBarLayout中,第二部给RecyclerView指定一个布局行为。
修改activity_main.xml中的代码,如下:
在这里插入图片描述
在这里插入图片描述
定义了一个AppBarLayout,并将Toolbar放置在了AppBarLayout中,然后在RecyclerView中使用app:layout_behavior属性指定了一个布局行为。其中appbar_scrolling_view_behavior这个字符串也是由Design Support库提供的。

刚刚说AppBarLayout中应用了一些Material Design的设计理念,好像从上面的例子体现不出来。

事实上,当RecyclerView滚动的时候就已经将滚动事件都通知给AppBarLayout了,只不过我们都没有处理而已。

(什么意思?)

下面进行优化,看看AppBarLayout能实现什么样的Material Design效果。

当AppBarLayout接收到滚动事件的时候,它内部的子控件其实是可以指定如何去影响这些事件的,通过app:layout_scrollFlags属性就能实现。

修改activity_main.xml中的代码,如下:
在这里插入图片描述

在Toolbar中添加了一个app:layout_scrollFlags属性,并将这个属性的值指定成了scroll|enterAlways|snap。
其中scroll表示当RecyclerView向上滚动的时候,Toolbar会跟着一起向上滚动并实现隐藏;
enterAlways表示当RecyclerView向下滚动的时候,Toolbar会跟着一起向下滚动并重新显示。
snap表示当Toolbar还没有完全隐藏或显示的时候,会根据当前滚动的距离,自动选择隐藏还是显示。

下拉刷新

SwipeRefreshLayout就是用于实现下拉刷新功能的核心类,它是由support-v4库提供的,我们想要把实现下拉刷新功能的控件放置到SwipeRefreshLayout中,就可以寻思让这个控件支持下拉刷新。

那么在刚刚的项目里,应该支持下拉刷新的空间自然就是RecyclerView了。

修改activity_main.xml:
在这里插入图片描述
在RecyclerView外面嵌套了一层SwipeRefreshLayout,这样RecyclerView就自动拥有下拉刷新功能了。

另外需要注意,由于RecyclerView现在变成了SwipeRefreshLayout的子控件,因此之前使用的app:layout_behavior声明的布局行为现在也要移到SwipeRefreshLayout中才行。

不过这还没有结束,虽然RecyclerView已经支持下拉刷新功能了,但还是要在代码中处理具体的刷新逻辑才行,
修改MainActivity中的代码,如下:

在这里插入图片描述
在这里插入图片描述
首先find到实例,然后setColorSchemeResources来设置下来刷新进度条的颜色,这里我们就使用主题中的colorPrimary作为进度条的颜色。
接着调用setOnRefreshListener方法来设置一个下拉刷新的监听器,当出发了下拉刷新操作的时候就会回调这个监听器onRefresh方法,然后我们在这里去处理具体的刷新逻辑就可以了。

通常情况下,onRefresh方法中应该是去网络上请求最新的数据,然后再将这些数据展示出来。这里简单起见,我们就不和网络进行交互了。
而是调用一个refreshFruits方法进行本地刷新操作。
refreshFruits方法中先是开启了一个线程,然后将线程沉睡两秒钟。
之所以折磨做,是因为本地刷新操作速度非常快,如果不将线程沉睡的话,刷新立刻就结束了,从而看不到刷新的过程。

沉睡结束之后,这里使用了runOnUiThread方法将线程切换回主线程,然后调用initFruits方法重新生成数据,接着再调用FruitAdapter的notifyDataSetChanged方法通知数据发生了变化,最后调用SwipreRefreshLayout的setRefreshing方法并传入false,用于表示刷新时间结束,并隐藏刷新进度条。

可折叠式标题栏

在这里插入图片描述

CollapsingToolbarLayout

顾名思义,CollapsingToolbarLayout是一个作用于Toolbar基础之上的布局,它也是由Design Support库提供的。CollapsingToolbarLayout可以让Toolbar的效果变得更加丰富,不仅仅是展示一个标题栏,而是能够实现非常华丽的效果。

不过,CollapsingToolbarLayout是不能独立存在的,它在设计的时候就被限定只能作为AppBarLayout的直接子布局来使用。而AppBarLayout又必须是CoordinatorLayout的子布局。

在这里插入图片描述
在这里插入图片描述
首先实现标题栏部分,这里使用CoordinatorLayout来作为最外层布局,如下:
在这里插入图片描述
注意始终记得要定义一个xmlns:app的命名空间,在Material Design的开发中常用它。

接着在CoordinatorLayout中嵌套一个AppBarLayout,如下:
在这里插入图片描述

接着在AppBarLayout中再嵌套一个CollapsingToolbarLayout,如图:
在这里插入图片描述
在这里插入图片描述
app:contentScrim属性用于指定CollapsingToolbarLayout在趋于折叠状态以及折叠之后的背景色,其实CollapsingToolbarLayout在折叠之后就是一个普通的Toolbar,那么背景色肯定应该是colorPrimary了。
app:layout_scrollFlags属性之前是给Toolbar指定的,现在移到外面来了。
其中scroll表示CollapsingToolbarLayout会随着水果内容详情的滚动一起滚动,exitUntilCollapsed表示当CollapsingToolbarLayout随着滚动完成折叠之后就保留在界面上,不再移出屏幕。

接下来,我们在CollapsingToolbarLayout中定义标题栏的具体内容,如下:
在这里插入图片描述
在这里插入图片描述
在CollapsingToolbarLayout中定义了一个ImageView和一个Toolbar,也就意味着,这个高级版的标题栏将是由普通的标题栏加上图片组合而成。
app:layout_collapseMode用于指定当前控件在CollapsingToolbarLayout折叠过程中的折叠模式,其中Toolbar指定成pin,表示在折叠的过程中位置始终保持不变,ImageView指定成parallax,表示在折叠过程中产生一定的错位偏移,这种模式的视觉效果会非常好。

下面编写水果内容详情部分。继续修改activity_fruit.xml中的代码,如下:
在这里插入图片描述
水果内容详情的最外层布局使用了一个NestedScrollView,注意它和AppBarLayout是平级的。

ScrollView它允许使用滚动的方式来查看屏幕以外的数据,而NestedScrollView在此基础伤害增加了嵌套响应滚动事件的功能。由于CoordinatorLayout本身已经可以响应滚动事件了,因此我们在它的内部就需要使用NestedScrollView或者RecyclerView这样的布局。
另外这里还通过app:layout_behavior属性指定了一个布局行为。

不管是ScrollView还是NestedScrollView,它们内部都只允许存在一个直接子布局。因此,如果想要放入很多东西的话,通常都会先嵌套一个LinearLayout,然后再在LinearLayout中放入具体的内容就可以了。如下:

在这里插入图片描述
这里嵌套一个垂直方向的LinearLayout,使用TextView来显示水果内容详情,并将TextView放在一个卡片式布局中,如图:
在这里插入图片描述
在这里插入图片描述
再加一个悬浮按钮
在这里插入图片描述
在这里插入图片描述
app:layout_anchor属性指定了一个锚点,将锚点设置为AppBarLayout,这样悬浮按钮就会出现在水果标题栏的区域内,接着又使用app:layout_anchorGravity,这样悬浮按钮就会出现在水果标题栏的区域内,接着又使用app:layout_anchorGravity属性将悬浮按钮定位再标题栏的有家教。

接下来编写逻辑功能,修改FruitActivity中的代码,如下:

在这里插入图片描述
在这里插入图片描述
通过Intetn获取到传入的水果名和水果图片的id(不太明白??)
在这里插入图片描述

处理RecyclerView的点击事件,如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
由于对UI不怎么感兴趣而且下午即将开学。。。偷懒偷懒!!!敲不进去了!!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值