Android5.0新特性实战(txt+pdf+epub+mobi电子书下载)

作者:李宁

出版社:中信出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Android5.0新特性实战

Android5.0新特性实战试读:

前言

Android自动诞生之初就有着强筋的发展势头,在数年来的发展过程中,也曾有过重大的升级。不过从来没有像Android5.0这样改变的如此彻底。不仅API发生了翻天覆地的变化(据说新增加了5000多个API),而且Google还为Android提供了新的技术:ART。这是一种可以将中间代码编译为二进制的技术。当APK安装时,系统会利用ART将其再次编译,然后才安装。所以在Android5.0上安装APK文件要略显慢一些。

由于在Android5.0之前,Google已经放出了一个Android L版本。可能很多读者经常搞混这两个版本。这两个版本的API Level总容易混。其实Android L的API Level不是数字,而是“L”。而Android5.0的API Level是21。不过可能是ADT没改过来。竟然将Android L的API Level显示成了21。不过不管怎么说,这两个版本的API大多数是兼容的。不过有一些API是发生了变化的。所以非常有必要重新让大家认识一个全新的Android5.0。这一版本有可能会成为Android的一个巅峰之作。因为从这个版本开始,Android不再使用传统的Dalvik虚拟机,而是使用Google的新技术ART。这种技术使程序运行得更快,更节省计算资源。

Android5.0提供的新功能非常多,本书不可能一一介绍,所以本书将以材料设计(Material Design)为主介绍Android5.0的这一UI技术。读者将从本书中体会到从拟物设计到扁平设计,从扁平设计到材料设计的进化。至于这种进化是否为良性的,还需要时间来验证。不过不管结果如何,材料设计正向我们走来。我们是应该张开双臂欢迎她呢?还是拒绝呢?相信正在阅读本书的读者已经给出了答案!作者介绍

李宁,东北大学计算机专业硕士,IT讲师、技术顾问。拥有超过10年的软件开发经验。曾任某知名企业项目经理,国内最早的Android和iOS实践者之一,对Android和iOS有深入的研究。精通Java、C、C++、Objective—C等语言。eoeAndroid论坛版主、中国移动开发者社区Android专家。曾在《程序员》、IT168等媒体上发表150多篇技术文章。曾出版《Android开发权威指南》、《Android深度探索卷1:HAL与驱动开发》等畅销书。第1章开发环境安装与配置

本章主要介绍了如何安装和配置Android5.0的开发环境。Android5.0和早期的版本在开发环境安装上基本相同,不过还是有些不太一样的地方。如果读者对这些方面都已经了解了,可以跳过对本章的学习。1.1 Android5.0 SDK的下载和安装

在安装Android5.0 SDK之前,应确定已经安装了JDK和Eclipse。接着下载Android SDK。最后启动Android SDK Manager(需要连接VPN),如图1-1所示。选择最新的Tools和Android5.0的SDK,然后点击“Install packages”按钮开始安装。图1-1 Android SDK Manager

安装Android5.0 SDK之前一定要安装最新的ADT,否则可能无法运行Android5.0的APP。1.2 启动Android 5.0模拟器

安装完Android SDK后,建立AVD的过程很普通(如果对此不了解的读者可以自己查询相关的资料)。不过有两点需要主要。首先要选择ARM处理器,然后需要勾选最后的“Use Host GPU”复选框,如果1-2所示。否则你的Android模拟器可能无法启动。图1-2 建立AVD1.3 如何让Android 5.0模拟器运行得更快

尽管使用ARM方式启动和使用Android5.0模拟器完全可行,不过用过Android模拟器的同学估计不被急死,也被气死了。真实太慢了!而且还容易死机。一开始我以为是内存或CPU不够造成的。不过自从在iMac 27 retina 5K顶配(CPU i7 4.0GHz,内存32G 1600,显卡:AMD Radeon R9 M295X 4GB GDDR5)运行了一次Android模拟器,就彻底绝望了。如果这个配置还低,个人计算机的配置就没有高的了。

实际上,Android模拟器运行得很慢,和当前机器的配置没有直接的关系(当然,配置太低也不行),而和ARM有关。如果选用ARM方式运行模拟器,系统会模拟一个ARM处理器来运行Android模拟器,而不会完全利用当前宿主机的CPU的GPU。所以无论宿主机的CPU和GPU有多高,只要选用ARM方式运行Android模拟器,都这速度。你就是在世界上最快的超级计算机上运行Android模拟器也是这个速度。

那么就没办法让Android模拟器运行得快一点的方法吗?答案是:Yes。方法是有,不过需要多做一些工作。解决这个问题的方式就是使用Intel x86模拟器加速器。这款加速器是专门为Android模拟器打造的。不过要记得只能在Intel的x86系列CPU上使用哦,其他的CPU,如AMD CPU,就得咨询相关厂商是否页提供了类似的加速器了。1.3.1 下载Intel x86模拟器加速器

首先说明一点,Intel x86模拟器加速器并不是必须安装(这里的安装是指随着Android SDK一起安装)的,所以如果想将Intel x86模拟器加速器安装到自己的宿主机器上,就要先确定加速器是否已经随Android SDK一起下载。

下载打开Android SDK Manager(不知道怎么打开的同学自己上网去查),如果发现无法下载相关的资源和列表,可以使用VPN(你懂的)。

在列表中找到Extras节点。然后找到Intel x86 Emulator Accelerator(HAXM installer)子节点(通常是Extras的最后一个子节点),如图1-3所示。如果子节点最后现实“Installed”,那么说明加速器已经随着Android SDK下载到本地了,否则需要选择该子节点进行安装(下载到本地)。图1-3 Android SDK Manager(安装X86镜像)1.3.2 安装Intel x86模拟器加速器

Intel x86模拟器加速器是跨平台的,支持Windows、Mac OS X和Linux。不管是哪个平台,都会在/extras/intel目录中找到一个Hardware_Accelerated_Execution_Manager目录(或类似的名字)。在该目录中包含了Intel x86模拟器加速器的安装程序。下面是Windows和OS X平台的安装方法。

Windows平台

该目录中通常是一个exe文件,例如intelhaxm.exe(或类似的名字),直接执行即可安装即可。

Mac OS X平台

最新的安装程序通常由两个img文件(OS X的安装程序)组成。一个是OS X 10.10(yosemite)版本的(IntelHAXM_1.1.0_for_10.10.img),另外一个适合于OS X 10.10以前的版本(IntelHAXM_1.1.0_below_10.10.img)。读者可以根据自己使用的OS X版本选择运行其中一个img文件。然后就是一路下一步,直到安装成功为止。

经测试,发现OS X10.10版本的img文件安装时有一些问题,安装成功了,但加速器的某些功能失效。如果读者发现有这些问题,那么就按下一节的方法从Intel官方下载最新的加速器安装包即可。1.3.3 从Intel官方下载最新的Intel X86模拟器加速器安装包

如果读者不想使用Android SDK中自带的加速器,也可以从Intel官方网站下载最新的加速器安装包。

首先进入如下的页面。

https://software.intel.com/en-us/android

页面右侧是Intel HAXM的下载页面链接,如图1-4所示。图1-4 Intel HAXM下载页面链接

点击“Download HAXM Now”链接,进入Intel HAXM下载页面。读者也可以直接使用下面的地址进入改下载页面。

https://software.intel.com/en-us/android/articles/intel-hardware-accelerated-execution-manager

在该页面提供了Windows、Max OS X和Linux三个平台的安装包的下载和安装方式。读者可以根据需要下载相应平台的安装包。安装方式相关页面写的很清楚,读者安装步骤做就可以。1.3.4 验证校验、停止和开启x86模拟器加速器

Windows平台

在控制台输入如下的命令。

sc query intelhaxm

如果成功安装了加速器,会显示相应的状态信息。

使用下面的命令停止加速器。

sc stop intelhaxm

使用下面的命令开启加速器。

sc start intelhaxm

Mac OS X平台

在终端输入下面的命令校验加速器是否安装成功。

kextstat | grep intel

如果成功安装了加速器,会输出相应的状态信息。

使用下面的命令停止加速器。

sudo kextunload –b com.intel.kext.intelhaxm

使用下面的命令开启加速器。

sudo kextload –b com.intel.kext.intelhaxm1.3.5 安装x86模拟器镜像

光安装模拟器加速器还不行。加速器不能作用于ARM的镜像,因此,必须安装x86模拟器镜像。

读者可以在Android SDK Manager中安装x86模拟器镜像。由于本书主要讲解的是Android5.0,所以只考虑Android5.0的x86模拟器镜像。其他Android版本的x86模拟器镜像安装方法类似。

现在打开Android SDK Manager,找到Android5.0部分,找到“Intel x86 Atom 64 System Image”(下面还有一个32位的,如果读者的机器安装了32位的OS,可以选这个),如图1-5所示。如果后面是“Installed”,所以该镜像已经安装了,否则需要选中安装。图1-5 Android SDK Manager

如果读者不想手动安装x86模拟器镜像,也可以从下面的地址下载最新的镜像文件。1.3.6 以x86模式运行Android模拟器

现在需要完成最后一步,建立一个AVD或修改已经存在的AVD。图1-6是一个AVD的最终配置。其中Device可以有多种选择,这里选择了Nexus 5(注意,选择Nexus 5,你的显示器分辨率要足够大哦,否则可显示不下)。Target选择Android 5.0。CPI/ABI选择Intel Atom(x86_64)。其他选项可根据需要选择。图1-6 AVD编辑窗口

现在可以启动Android模拟器了,从启动就可以看出来,速度非常快(和以ARM模式运行的Android模拟器相比)。成功启动后的界面如图1-7所示。从表面看起来和基于ARM的Android模拟器没什么不同。不过大家可以操作一下Android模拟器,速度真是杠杠的。和在真机上操作的速度几乎一样。图1-7 以x86模式运行的Android模拟器1.4 小结

由于Android模拟器运行太慢,所以Intel开发了x86加速器,允许Android模拟器使用宿主机的GPU和CPU,这将大大提升Android模拟器的运行速度,所以强烈建议使用x86加速器来运行Android模拟器。第2章材料(Material)主题

材料主题是采用材料设计最先遇到的技术。Android5.0为材料设计提供了几个主题,用于配合其他效果的实现。本章将主要介绍Android5.0提供了哪些材料主题,以及如何使用这些材料主题。2.1 使用不同的材料主题

Android 5.0提供了多种用于材料设计的主题,如果读者决定采用Material Design设计App,不妨从如下的主题开始。

·@android:style/Theme.Material :黑色风格

·@android:style/Theme.Material.Light :高亮风格

·@android:style/Theme.Material.Light.DarkActionBar:黑色动作条

为App设置这些主题有多种方法,不过这些主题只针对与Android5.0,所以在设置这些主题之前,应先打开AndroidManifest.xml文件。讲android:minSdkVersion和targetSdkVersion都设置为21。代码如下:

如果不这样设置,是不允许设置这些主题的,如果强行设置,Android工程将编译出错。

修改App的主题有多种方法,最直接的就是修改AndroidManifest.xml文件中的标签的android:theme属性。该属性的默认值是@style/AppTheme,代码如下: … …

当然,还有其他的方法可以设置App的主题。例如,修改styles.xml文件中

现在运行程序,会看到如图2-2所示的效果。从表面上看,好像只有颜色发生了改变,其他的照旧。如果只有自己点击一下上面的菜单和下面的控件,才会发现真的和以前不同。图2-2 Theme.Material主题效果

最明显的特征是加入了点击动画,当点击CheckBox和右上角Settings菜单时,会显示点击动画,如图2-3和2-4所示。图2-3 点击CheckBox控件产生的动画效果图2-4 点击CheckBox控件参数的动画效果

读者也可以用上述方法测试其他的材料主题。如图2-5所示是Theme.Material.Light主题的效果,该主题以亮色为主。点击效果和Theme.Material类似。图2-5 Theme.Material.Light主题的效果2.2 修改材料主题的默认属性值

我们不仅可以使用材料主题的默认风格,还可以修改材料主题的属性值,按着我们自己的要求定制材料主题。

修改主题的方法很简单,只要在

如果按着这个设置,效果如图2-6所示。图2-6 定制材料主题后的效果

可能有的读者会提出这样的问题,我怎么知道要设置哪个属性呢?还有材料主题使用了哪些属性我怎么知道呢?实际上,我们可以从Android SDK中很容易找到这些主题使用的属性以及属性值。

读者可以进入Android SDK目录,然后导航到如下的子目录。

/platforms/android-21/data/res/values

在values目录中找到themes_material.xml文件,所以和材料设计相关的主题和所设置的属性都在该文件中。读者可以根据自己的需要定制这些属性的值。2.3 小结

材料主题的使用方法和普通的材料主题相同,不过要想将材料设计用于自己的App,最好使用这些材料主题。因为他们提供的效果可以和其他的材料设计效果融为一体。第3章Android5.0提供的新控件

Android5.0提供了一些新的控件,其中RecyclerView和CardView是最受关注的两个新控件。前者是ListView的增强版,后者用于有立体质感的卡片效果。本章将通过大量的案例详细介绍这两个控件的使用方法。3.1 RecyclerView控件简介

我们可以将RecyclerView控件看做是ListView控件的升级版。该控件除了支持一些特效外,最引人注目的是不近支持纵向显示列表,还支持横向现实列表。

RecyclerView在使用方法和基本原理上和ListView类似。不过某些方法名称和API发生了一些变化。

由于RecyclerView支持水平、垂直方向的列表。所以,在使用RecyclerView控件时,要为该控件指定一个LinearLayoutManager对象,该对象用于管理线性布局。这里的布局就是指RecyclerView控件中所有Item之间的布局。如果LinearLayoutManager设置为垂直线性布局,那么RecyclerView就和ListView一样,是纵向的列表。如果LinearLayoutManager设置为水平线性布局,那么RecyclerView就变成横向的列表了。

当然,RecyclerView的功能还远不止这些,除了支持Item的垂直和水平线性布局外,还支持如下两个更复杂的Item布局。

·GridLayoutManager:所有的Item呈网格形式的布局。

·StaggeredGridLayoutManager:所有的Item呈交错网格形式的布局。

除此之外,我们还可以更灵活地定制RecyclerView控件。例如,可以通过RecyclerView.addItemDecoration方法定制Item之间的分隔线(需要指定一个Drawable对象),如果不指定,这无分隔线。使用RecyclerView. setItemAnimator方法指定Item的动画效果,如果不指定,则无动画效果。

在前面列举的功能都是为了实现RecyclerView的特效。但却忽略了RecyclerView控件最本质的功能,也就是装载数据。

RecyclerView和ListView一样,也需要通过Adapter提供数据,并在Adapter中完成对数据的操作。不过Adapter的某些需要实现的方法与ListView的Adapter有所不同。不过不管Adapter如何实现,在创建完Adapter对象后,仍然必须使用RecyclerView.setAdapter方法为RecyclerView指定Adapter对象。

可能通过本节的只言片语还无法了解如何使用RecyclerView控件,不过不用着急,在接下来的两节中,将会通过完整的例子来演示如何使用RecyclerView控件的核心API。3.2 用RecyclerView控件实现垂直列表效果

本节的例子将使用RecyclerView控件实现一个垂直列表的效果。其中可以动态添加和删除列表项。在这个例子中,除了演示RecyclerView控件的用法外,还演示了其他物料设计特效的实现,例如,为按钮加阴影。本例的效果如图3-1所示。图3-1 垂直列表的效果

点击右下角的圆形按钮,将添加一个Item。当列表向下拉时,会在列表上方现实“Delete”面板(实际上是一个FrameLayout),点击改面板将删除已经显示出的列表项中的第一个列表项。3.2.1 建立Model

由于RecyclerView控件使用MVC方式管理数据,所以需要先为Adapter准备一些要现实的数据。本例提供的数据很简单,只是通过数据提供的若干个SampleModel对象。SampleModel类的代码会在本节后面给出,这里先看一下DemoApp类,该类通过静态方法getSampleData返回了这些数据,该类的代码如下:package mobile.android.material.recyclerview;import java.util.ArrayList;public class DemoApp { // 获取要显示的数据(初始化数据) public static ArrayList getSampleData (int size) { ArrayList sampleData = new ArrayList(size); for (int i = 0; i < size; i++) { // 每一项数据后面都有相应的序列号 sampleData.add(new SampleModel("新的列表项<"+i + ">")); } return sampleData; }}

在getSampleData方法中使用了一个SampleModel类,该类封装了每一个列表项的数据,代码如下:package mobile.android.material.recyclerview;public class SampleModel { private String sampleText; public SampleModel(String sampleText) { this.sampleText = sampleText; } public void setSampleText(String sampleText) { this.sampleText = sampleText; } public String getSampleText() { return sampleText; }}

从SampleModel类的代码可以看出,该类只有一个String类型的字段,用于保存列表项的文本。读者可以根据实际需要添加其他的字段。3.2.2 定制列表项的分隔条

使用RecyclerView控件通常需要指定列表项的分隔条。定制分隔条的基本原理是编写一个RecyclerView.ItemDecoration的子类,并实现onDrawOver方法。在该方法中需要绘制所有列表项之间的分隔条。

定制分隔条的实现类是SampleDivider,该类的代码如下:package mobile.android.material.recyclerview;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.drawable.Drawable;import android.support.v7.widget.RecyclerView;import android.view.View;public class SampleDivider extends RecyclerView.ItemDecoration { // 默认分隔条Drawable资源的ID private static final int[] ATTRS = { android.R.attr.listDivider }; // 分隔条Drawable对象 private Drawable mDivider; public SampleDivider(Context context) { TypedArray a = context.obtainStyledAttributes(ATTRS); // 获取分隔条的Drawable对象 mDivider = a.getDrawable(0); // 回收TypedArray所占用的空间(已经获取了指定的资源,不再需要TypedArray了) a.recycle(); } // 在该方法中绘制了所有列表项之间的分隔条 @Override public void onDrawOver(Canvas c, RecyclerView parent) { // 获取列表项距离左边缘的距离 int left = parent.getPaddingLeft(); // 获取列表项距离右边缘的距离 int right = parent.getWidth() - parent.getPaddingRight(); // 获取列表项总数 int childCount = parent.getChildCount(); // 开始绘制这些列表项之间的分割线 for (int i = 0; i < childCount; i++) { // 获得当前的列表项 View child = parent.getChildAt(i); // 获取当前列表项的布局参数信息 RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); // 计算分隔条左上角的纵坐标int top = child.getBottom() + params.bottomMargin;// 计算分隔条右下角的纵坐标 int bottom = top + mDivider.getIntrinsicHeight(); // 设置分隔条绘制的位置mDivider.setBounds(left, top, right, bottom);// 开始绘制当前列表项下方的分隔条 mDivider.draw(c); } }}3.2.3 实现Adapter类

Adapter用于为RecyclerView控件提供数据,所以在开始使用RecyclerView控件控件之前,需要先实现一个Adapter类。

RecyclerView提供了新的Adapter基类RecyclerView.Adapter,该基类支持泛型,泛型用于指定列表项中的控件。本例实现的Adapter类是SampleRecyclerAdapter,代码如下:package mobile.android.material.recyclerview;import java.util.ArrayList;import java.util.Random;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class SampleRecyclerAdapter extends RecyclerView.Adapter { // 保存列表项数据 private final ArrayList sampleData = DemoApp.getSampleData(20); // 创建列表项中显示的控件的对象(需要使用Adapter指定的泛型) @Overridepublic ViewHolder onCreateViewHolder(ViewGroup parentViewGroup, int i) { // 获取列表项控件(LinearLayer对象) // list_basic_item.xml布局文件中只包含一个标签,在该标签中 // 包含一个标签 View rowView = LayoutInflater.from (parentViewGroup.getContext()) .inflate(R.layout.list_basic_item, parentViewGroup, false); return new ViewHolder (rowView); } // 在该方法中设置列表项控件中显示的值 @Override public void onBindViewHolder(ViewHolder viewHolder, final int position) { final SampleModel rowData = sampleData.get(position); // 设置要显示的值 viewHolder.textViewSample.setText(rowData.getSampleText()); viewHolder.itemView.setTag(rowData); } // 获取列表项总数 @Override public int getItemCount() { return sampleData.size(); } // 删除指定位置的列表项数据 public void removeData (int position) { sampleData.remove(position); // 通知RecyclerView控件某个列表项已经被删除了 notifyItemRemoved(position); } // 在指定位置添加一个新的列表项 public void addItem(int positionToAdd) { // 使用随机数区分新添加的列表项 sampleData.add(positionToAdd, new SampleModel("新的列表项" + new Random().nextInt(10000))); // 通知RecyclerView控件,在指定位置已经添加了一个新的列表项 notifyItemInserted(positionToAdd); } // 用于存储列表项中显示的控件(本例只有一个TextView控件) public static class ViewHolder extends RecyclerView.ViewHolder { private final TextView textViewSample; public ViewHolder(View itemView) { super(itemView); textViewSample = (TextView) itemView.findViewById( R.id.textViewSample); } }}

SampleRecyclerAdapter类中所有使用@Override的方法都是覆盖的父类的同名方法。这些方法和传统的ListView和对应的Adapter中使用的类似方法有一些不同。例如,在新的Adapter方法中不再有getView方法。而使用onCreateViewHolder和onBindViewHolder方法。前者用于获取列表项控件,后者用于指定在控件中显示的数据。还有就是通知RecyclerView控件数据发生改变的方法也发生了变化。以前只能使用notifyDataSetChanged方法通知数据是否发生变化,现在可以使用notifyItemRemoved方法通知列表项被删除,使用notifyItemInserted方法通知某一个新的列表项被添加。当然,新的Adapter的改进还有很多,大家可以在使用的过程中逐渐体会。3.2.4 如何使用RecyclerView控件

从RecyclerView的官方文档可以看出,该类的全名是android.support.v7.widget.RecyclerView。很明显,该类在API Level = 7的兼容包中。凡是使用过最新的Android SDK和ADT创建Android工程都会发现一个名为android-support-v7-appcompat.jar的Library。其中的类兼容了API Level = 7及以上的Android SDK。不过很疑惑,在这个Library中并没有找到RecyclerView类。那么这个类到底在哪里呢?

其实这个Library只是Android Support Library中的一个,如果读者在安装Android SDK时已经安装了Android Support Library(如图3-2所示),那么所有的Android Support Library都会下载到本机。图3-2 安装Android Support Library

假设下载读者已经安装了Android Support Library。现在进入Android SDK的根目录。并导航到extra/android/support/v7目录。会发现在该目录中包含了如下6个目录,如图3-3所示。其中appcompat目录就是android-support-v7-appcompat.jar的源代码和二进制文件(jar文件)。其他5个目录都是Android5.0 SDK新支持的控件。其中recyclerview就是RecyclerView控件对应的jar文件所在的目录(RecyclerView控件并没有带源代码)。当然,如果读者为了省事,可以讲这些目录中的jar文件都复制到Android工程的libs目录(只能是这个目录),并引用这些jar文件即可。或者只复制需要的jar文件也可以。图3-3 Android Support Library目录

现在进入recyclerview/libs目录,会发现一个android-support-v7-recyclerview.jar文件。安装前面介绍的方法并引用该jar文件就可以使用RecyclerView控件了。3.2.5 用RecyclerView控件实现增加和删除列表项的效果

现在一切准备工作都已经就绪了。下面就来实现本例的主程序。创建RecyclerView控件,并利用前面编写的Adapter、Model等类对RecyclerView控件进行初始化,并显示列表数据。

本例的主类是MainActivity,该类的代码如下:package mobile.android.material.recyclerview;import android.app.Activity;import android.graphics.Outline;import android.os.Bundle;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.view.View;import android.view.ViewOutlineProvider;import android.view.animation.AnimationUtils;import android.widget.FrameLayout;public class MainActivity extends Activity{ // 后下角的删除按钮 private FrameLayout mDeleteBar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 获取删除按钮对象 mDeleteBar = (FrameLayout) findViewById(R.id.deleteBar); // 为按钮增加的阴影(轮廓) Outline fabOutline = new Outline(); // 通过ViewOutlineProvider获取引用的位置和尺寸 ViewOutlineProvider viewOutlineProvider = new ViewOutlineProvider() { @Override public void getOutline(View view, Outline outline) { // 获取阴影的尺寸 int fabSize = getResources().getDimensionPixelSize(R.dimen.fab_size); // 设置阴影的绘制位置和尺寸 outline.setOval(-4, -4, fabSize + 2, fabSize + 2); } }; View fabView = findViewById(R.id.fab_add); fabView.setOutlineProvider(viewOutlineProvider); // 获取RecyclerView对象 final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view); // 创建LinearLayoutManager对象(默认是垂直方向的) final LinearLayoutManager layoutManager = new LinearLayoutManager(this); // 为RecyclerView指定布局管理对象 recyclerView.setLayoutManager(layoutManager); // 创建列表项分隔线对象 final RecyclerView.ItemDecoration itemDecoration = new SampleDivider(this); // 为RecyclerView控件指定分隔线对象 recyclerView.addItemDecoration(itemDecoration); // 创建SampleRecyclerAdapter对象 final SampleRecyclerAdapter sampleRecyclerAdapter = new SampleRecyclerAdapter(); // 为RecyclerView控件指定Adapter recyclerView.setAdapter(sampleRecyclerAdapter); // 为右下角的添加按钮设置单击事件 fabView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 获取第一个可视的列表项的位置 int positionToAdd = layoutManager.findFirstCompletelyVisibleItemPosition(); // 在该位置的后面插入新的列表项 sampleRecyclerAdapter.addItem(positionToAdd); } }); // 为列表上方的删除面板设置单击事件 mDeleteBar.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // 获取第一个可视的列表项的位置 int positionToRemove = layoutManager.findFirstCompletelyVisibleItemPosition(); // 删除第一个可视的列表项 sampleRecyclerAdapter.removeData(positionToRemove); // 删除完后会隐藏删除面板 hideDeleteBar(); } }); // 为RecyclerView控件设置滚动事件 recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { // 滚动状态变化事件方法 @Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) { // TODO Auto-generated method stub super.onScrollStateChanged(recyclerView, newState); } // 滚动事件方法(判断上下或左右滚动) @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { // TODO Auto-generated method stub super.onScrolled(recyclerView, dx, dy); // 如果是垂直显示的列表。dy>0表示向上滚动,否则表示向下滚动 // 如果是水平显示,dx > 0表示向右滚动,否则向左滚动 if (dy > 0) { // 向上滚动时隐藏删除面板 if (mDeleteBar.getVisibility() == View.VISIBLE) hideDeleteBar(); } else { // 向下滚动时显示显示面板 if (mDeleteBar.getVisibility() == View.GONE) showDeleteBar(); } } }); } // 以动画方式显示删除面板 private void showDeleteBar() { mDeleteBar.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate_up_on)); mDeleteBar.setVisibility(View.VISIBLE); } // 以动画方式隐藏删除面板 private void hideDeleteBar() { mDeleteBar.startAnimation(AnimationUtils.loadAnimation(this, R.anim.translate_up_off)); mDeleteBar.setVisibility(View.GONE); }}

下面看一下MainActivity使用的布局文件(activity_main.xml)的完成代码。 3.3 用RecyclerView控件实现画廊的效果

RecyclerView控件的强大之处就是不仅仅可以替代ListView控件,还可以替代Gallery控件,实现水平的滚动效果。本节将给出一个使用RecyclerView控件实现水平滚动画廊的效果。当点击某个Item时,在RecyclerView控件上方会显示当前Item的大图,效果如图3-4所示。

试读结束[说明:试读内容隐藏了图片]

下载完整电子书

若在网站上没有找合适的书籍,可联系网站客服获取,各类电子版图书资料皆有。

客服微信:xzh432

登入/注册
卧槽~你还有脸回来
没有账号? 忘记密码?