碎片(Fragment)是一种可以嵌入在活动中的UI片段,它能让程序更加合理和充分的利用大屏幕的空间,因而在平板上应用的相当广泛。虽然碎片对你来说应该是个全新的概念,但是相信大家学习起来应该毫不费力,因为它和活动实在太像了。同样都能包含布局,同样都有自己的生命周期。你甚至可以讲话碎片理解成一个迷你性活动,虽然这个迷你型活动有可能和普通德 活动是一样大的。
那么究竟要如何使用碎片才能充分的利用平板屏幕的空间啦?想象一下我们正在开发一个新闻应用,其中一个界面要使用Recycleview展示了一组新闻的标题,当点击了其中一个标题时,就打开另一个界面新闻的详细内容。如果实在手机中设计,我们可以将新闻标题列表放在一个活动中,将新闻的详细内容放在另一个活动中,
可以如果在品班上也这么设计,那么新闻标题列表就会被拉长至填充满整个平板的屏幕,而新闻的标题一般都不会太长,这样将会导致界面上有大量的空白区域,如图
因此,更好的设计方案是将新闻标题列表界面和新闻详细内容界面分别放在两个碎片中,然后在同一个活动里引入这两个碎片,这样就可以将屏幕空间充分的利用起来了,如图所示:
4.2 碎片的使用方式
介绍了这么多抽象的东西,也是时候学习一下具体的用法了。你已经知道,碎片通常都是在平板开发中使用的,因此我们首先要做的就是创建一个平板模拟器。创建模拟器的方法我们在第一张的学习过了。创建完成后启动平板模拟器,效果图所示:
好了,贮备工作都完成了,接着新建一个FragmentTest项目,然后开始我们的碎片太多之旅吧!。
4.2.1 碎片的单间使用
这里我们准备先写好一个简单的碎片实例来练练手,在一个活动中添加两个碎片,并让这个两个两个碎片评分活动空间。
新建一个左侧Fragment,代码如下:
这个布局非常简单,只放置一个按钮,并让他水平居中显示。然后新建一个右侧碎片布局
可以看到,我们将这个布局的背景设置成了绿色,并放置了一个TextView用于一段文本。
接着新建一个leftFragment类,并继承自Fragment。注意,这里可能会有连个不同的Fragment供你选择,一个时系统内置的Fragment,一个是V4包的Fragment。这里我们强烈建议使用V4包里面的Fragment,因为它可以让碎片在所有Android系统版本中保持功能一致性。比如说zaiFragment中嵌套使用Fragment这个功能是在Android4.2系统中才开始支持的,如果你使用的是系统内置的Fragment,那么很遗憾,4.2系统以前的系统就会崩溃。而使用V-4库中的Fragment就不会出现这个问题,只要你保证使用的是最新的V-4库就可以了。另外,我们并不需要在buidl.gradle文件中添加V-4依赖,因为buile.gradle文件中已经添加了appcompat-v7库的依赖,而这个库会将V-4库一起引入进来。
现在编写一个Fragment中的代码,如下所示:
这里仅仅是重写了Fragment的onCreateView()方法,然后在这个方法中通过LayoutInflater的inflate()方法将刚才定义的fragment布局动态加载进来,整个方法简单明了。接着我们用同样的方法在新建一个RightFragment:。。。。。
基本上代码是相通的,相信已经没哟必要再做任何解释了。接下来直接将两个Fragment作为布局文件写入到Main_Activity里面。
可以看到,我们使用<fragment>标签在布局中添加碎片,其中指定的大多数属性都是你熟悉的,只不过还需要通过android:name属性来显示指明要添加的碎片类名,注意一定要将包名也加上。
这样最重要的碎片示例就已经写好了,现在运行一下,效果
正如我们期待的一样,两个碎片平分了整个活动的布局。不过这个例子实在是太简单了,在真正的项目中很难有什么实际作用因此我们马上来看看,关于碎片更加高级的使用技巧。
4.2.2 动态添加碎片
在上一节当中,你已经学会了在布局文件中添加碎片的方法,不过碎片真正的强大之处在于,你可以在程序运行时动态的添加碎片,你就可以将程序界面定制得更加多样化。
我们还是在上一节代码的基础上继续完善,新建another_right_fragment
.xml,代码如下所示:
代码同样非常简单,在onCreatView方法中加载了刚刚创建的anotherfragment布局。这样我们就准备好了另一个碎片,接下来看一下如何将它动态地添加到活动当中。修改activity.xml,代码中:
可以看到,现在将右侧碎片替换成一个framelayout中,还记得布局吗?在上一张章中我们学过,这是Android中最简单一种布局,所有的控件默认都会摆在布局的左上角。由于这里需要再不聚方法入一个碎片,不需要任何定位,因此非常适合使用FrameLayout。
下面我们将代码中向FrameLayout里添加内容,从而实现动态添加碎片功能。修改MainActivity中的代码,如下所示:
可以看到,首先我们给左侧碎片中的按钮注册了一个点击事件,然后调用replaceFragment()方法动态添加了RightFragment这个碎片。当点击左侧碎片中的按钮时,又会调用replaceFragment()方法将右侧的碎片替换成AotherFragment。结合replaceFragment()方法中的代码可以看出,动态添加碎片主要分为5步。
(1)创建待添加的碎片实例
(2)获取FragmentManger,在活动中可以直接通过调用getSupportFragmentManger()方法得到。
(3)开启一个事务,通过调用beginTransaction()方法开启。
(4)向容器内添加或替换碎片,一般使用replace()方法实现,需要出传入容器的id和待添加的碎片实例。
(5)提交事务,调用commit()方法完成。
这样就完成了在活动中动态添加碎片的功能,重新运行程序,可以看到和之前相同的界面,然后点击一下按钮,效果如图所示
4.2.3 在碎片中模拟返回栈
在上一节中,我们成功实现了向活动中动态添加碎片的功能,不过尝试一下就会发现,通过点击按钮添加了一个碎片之后,这是按下Back键程序就会直接退出。如果这里我们想模拟雷诗雨返回栈的效果,按下Back键可以回到上一个碎片,该如何实现啦?
其实很简单,FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事物添加到返回栈的效果,按下Back键可以回到上一个碎片,该如何实现?
从修改MainActivity中的代码如下:
这里我们在事务提交之前调用了FragmentTransaction的addTobackStack()方法,特可以接收一个名字用于描述返回栈的状态,一般传入null即可。现在重新运行程序,并点击按钮将AotherFragment添加到活动中,然后按下Back键,你会发现程序并没有退出,而是回到了RightFragment界面,继续按下Back键,RightFragment界面也会消失,再次按下Back键,程序才会退出。