Android Fragment的用法(一)
1、碎片是什么
碎片(Fragment)是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛。虽然碎片对你来说应该是个全新的概念,但我相信你学习起来应该毫不费力,因为它和活动实在是太像了,同样都能包含布局,同样都有自己的生命周期。你甚至可以将碎片理解成一个迷你型的活动,虽然这个迷你型的活动有可能和普通的活动是一样大的。
那么究竟要如何使用碎片才能充分地利用平板屏幕的空间呢?想象我们正在开发一个新闻应用,其中一个界面使用ListView展示了一组新闻的标题,当点击了其中一个标题,就打开另一个界面显示新闻的详细内容。如果是在手机中设计,我们可以将新闻标题列表放在一个活动中,将新闻的详细内容放在另一个活动中,如图1所示。

图1
可是如果在平板上也这么设计,那么新闻标题列表将会被拉长至填充满整个平板的屏幕,而新闻的标题一般都不会太长,这样将会导致界面上有大量的空白区域,如图2所示。

图2
因此,更好的设计方案是将新闻标题列表界面和新闻详细内容界面分别放在两个碎片中,然后在同一个活动里引入这两个碎片,这样就可以将屏幕空间充分地利用起来了,如图3所示。

图3
2、碎片的使用方式
新建一个FragmentTest项目,然后开始我们的碎片探索之旅吧。
新建一个左侧碎片布局left_fragment.xml,代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" > <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="Button"
/> </LinearLayout>
这个布局非常简单,只放置了一个按钮,并让它水平居中显示。然后新建右侧碎片布局right_fragment.xml,代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#00ff00"
android:orientation="vertical" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is right fragment"
/> </LinearLayout>
可以看到,我们将这个布局的背景色设置成绿色,并放置了一个TextView用于显示一段文本。接着新建一个LeftFragment类,继承自Fragment。注意,这里可能会有两个不同包下的Fragment供你选择,建议使用android.app.Fragment,因为我们的程序是面向Android 4.0以上系统的,另一个包下的Fragment主要是用于兼容低版本的Android系统。LeftFragment的代码如下所示:
public class LeftFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.left_fragment, container, false);
return view;
}
}
这里仅仅是重写了Fragment的onCreateView()方法,然后在这个方法中通过LayoutInflater的inflate()方法将刚才定义的left_fragment布局动态加载进来,整个方法简单明了。接着我们用同样的方法再新建一个RightFragment,代码如下所示:
public class RightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.right_fragment, container, false);
return view;
}
}
新建another_right_fragment.xml,代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffff00"
android:orientation="vertical" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:text="This is another right fragment"
/> </LinearLayout>
这个布局文件的代码和right_fragment.xml中的代码基本相同,只是将背景色改成了黄色,并将显示的文字改了改。然后新建AnotherRightFragment作为另一个右侧碎片,代码如下所示:
public class AnotherRightFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.another_right_fragment, container, false);
return view;
}
}
代码同样非常简单,在onCreateView()方法中加载了刚刚创建的another_right_fragment布局。这样我们就准备好了另一个碎片,接下来看一下如何将它动态地添加到活动当中。修改activity_main.xml,代码如下所示:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 静态加载Fragment -->
<fragment
android:id="@+id/left_fragment"
android:name="com.example.fragmenttest.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" /> <FrameLayout
android:id="@+id/right_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
<!-- 可以在这个容器中动态加载Fragment -->
<fragment
android:id="@+id/right_fragment"
android:name="com.example.fragmenttest.RightFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" /> </FrameLayout> </LinearLayout>
可以看到,现在将右侧碎片放在了一个FrameLayout中,这是Android中最简单的一种布局,它没有任何的定位方式,所有的控件都会摆放在布局的左上角。由于这里仅需要在布局里放入一个碎片,因此非常适合使用FrameLayout。
之后我们将在代码中替换FrameLayout里的内容,从而实现动态添加碎片的功能。修改MainActivity中的代码,如下所示:
public class MainActivity extends Activity implements OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
AnotherRightFragment fragment = new AnotherRightFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager. beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.commit();
break;
default:
break;
}
}
}
可以看到,首先我们给左侧碎片中的按钮注册了一个点击事件,然后将动态添加碎片的逻辑都放在了点击事件里进行。结合代码可以看出,动态添加碎片主要分为5步。
- 创建待添加的碎片实例。
- 获取到FragmentManager,在活动中可以直接调用getFragmentManager()方法得到。
- 开启一个事务,通过调用beginTransaction()方法开启。
- 向容器内加入碎片,一般使用replace()方法实现,需要传入容器的id和待添加的碎片实例。
- 提交事务,调用commit()方法来完成。
这样就完成了在活动中动态添加碎片的功能,运行程序,可以看到启动界面如图4所示,然后点击一下按钮,效果如图5所示。

图4

图5
3、在碎片中模拟返回栈
我们成功实现了向活动中动态添加碎片的功能,不过你尝试一下就会发现,通过点击按钮添加了一个碎片之后,这时按下Back键程序就会直接退出。如果这里我们想模仿类似于返回栈的效果,按下Back键可以回到上一个碎片,该如何实现呢?
其实很简单,FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中,修改MainActivity中的代码,如下所示:
public class MainActivity extends Activity implements OnClickListener {
……
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
AnotherRightFragment fragment = new AnotherRightFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction transaction = fragmentManager. beginTransaction();
transaction.replace(R.id.right_layout, fragment);
transaction.addToBackStack(null);
transaction.commit();
break;
default:
break;
}
}
}
这里我们在事务提交之前调用了FragmentTransaction的addToBackStack()方法,它可以接收一个名字用于描述返回栈的状态,一般传入null即可。现在重新运行程序,并点击按钮将AnotherRightFragment添加到活动中,然后按下Back键,你会发现程序并没有退出,而是回到了RightFragment界面,再次按下Back键程序才会退出。
4、碎片和活动之间进行通信
虽然碎片都是嵌入在活动中显示的,可是实际上它们的关系并没有那么亲密。你可以看出,碎片和活动都是各自存在于一个独立的类当中的,它们之间并没有那么明显的方式来直接进行通信。如果想要在活动中调用碎片里的方法,或者在碎片中调用活动里的方法,应该如何实现呢?
为了方便碎片和活动之间进行通信,FragmentManager提供了一个类似于findViewById()的方法,专门用于从布局文件中获取碎片的实例,代码如下所示:
RightFragment rightFragment = (RightFragment) getFragmentManager().findFragmentById(R.id.right_fragment);
调用FragmentManager的findFragmentById()方法,可以在活动中得到相应碎片的实例,然后就能轻松地调用碎片里的方法了。
掌握了如何在活动中调用碎片里的方法,那在碎片中又该怎样调用活动里的方法呢?其实这就更简单了,在每个碎片中都可以通过调用getActivity()方法来得到和当前碎片相关联的活动实例,代码如下所示:
MainActivity activity = (MainActivity) getActivity();
有了活动实例之后,在碎片中调用活动里的方法就变得轻而易举了。另外当碎片中需要使用Context对象时,也可以使用getActivity()方法,因为获取到的活动本身就是一个Context对象了。
这时不知道你心中会不会产生一个疑问,既然碎片和活动之间的通信问题已经解决了,那么碎片和碎片之间可不可以进行通信呢?
说实在的,这个问题并没有看上去的复杂,它的基本思路非常简单,首先在一个碎片中可以得到与它相关联的活动,然后再通过这个活动去获取另外一个碎片的实例,这样也就实现了不同碎片之间的通信功能,因此这里我们的答案是肯定的。
Android Fragment的用法(一)的更多相关文章
- Android Fragment的用法(二)
如果你经常使用平板电脑,应该会发现很多的平板应用现在都采用的是双页模式(程序会在左侧的面板上显示一个包含子项的列表,在右侧的面板上显示内容),因为平板电脑的屏幕足够大,完全可以同时显示下两页的内容,但 ...
- android fragment 的用法以及与activity的交互和保存数据的方法,包括屏幕切换(转载)!
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/37992017 1.管理Fragment回退栈 类似与Android系统为Acti ...
- 009 Android Fragment动态用法(实现动态菜单栏)设置控件为满屏状态
·1.MainActivity采用线性布局 2.在app--->res--->layout,右击new--->xml---->layout xml FILE <1> ...
- Android Fragment碎片
什么是碎片? 碎片(Fragment)是一种可以嵌入在活动当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛.可以把Fragment当成Activity一个界面的一 ...
- Android Fragment用法知识点的讲解
Android Fragment用法的讲解 碎片,它的出现是为了更好展示UI的设计,让程序更加得到充分的展示.Fragment的出现,如微信的额主界面包含多个Fragment,使得微信功能更加简洁明了 ...
- Android Fragment和FragmentActivity区别和用法
Android Fragment是Android4.0以上才有的:而FragmentActivity是为了兼容4.0以下版本的Fragment使用的. 所以如果你想兼容4.0以下Android版本使用 ...
- Android Fragment用法详解(2)--动态添加Fragment
在上一篇文章<Android Fragment用法详解(1)--静态使用Fragment>我们讲解了Fragment的最简单的用法.这次我们来说一说Fragment复杂一丢丢的用法.在代码 ...
- 【Android自学日记】【转】Android Fragment 真正的完全解析(下)
上篇博客中已经介绍了Fragment产生原因,以及一些基本的用法和各种API,如果你还不了解,请看:Android Fragment 真正的完全解析(上). 本篇将介绍上篇博客提到的:如何管理Frag ...
- Android Fragment应用实战
现在Fragment的应用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时候,主要是为了解决Android Pad屏幕比较大,空间不能充分利用的问题,但现在即使只是在手机上, ...
随机推荐
- NIO类库
NIO概述 从JDK1.4开始,引入了新的I/O类库,它们位于java.nio包中,其目的在于提高I/O的操作效率.nio是new io的缩写. 参考文章:NIO BIO AIO区别 java.nio ...
- [Swift]LeetCode302. 包含黑色像素的最小矩形 $ Smallest Rectangle Enclosing Black Pixels
An image is represented by a binary matrix with 0 as a white pixel and 1 as a black pixel. The black ...
- [Swift]LeetCode894. 所有可能的满二叉树 | All Possible Full Binary Trees
A full binary tree is a binary tree where each node has exactly 0 or 2 children. Return a list of al ...
- less环境的安装与搭建
less: Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合(mixin).函数等功能,让 CSS 更易维护.方便制作主题.扩充.Less 可以运行在 Node 或浏 ...
- SpringBoot + SpringCloud学习踩坑实记
踩的坑: 1).springcloud框架中,依赖一直报错,很可能是没有添加springcloud的依赖,或者是依赖的版本号过低.并且springboot也有一个父依赖. 2.springcloud ...
- 原有vue项目接入typescript
原有vue项目接入typescript 为什么要接入typescript javascript由于自身的弱类型,使用起来非常灵活. 这也就为大型项目.多人协作开发埋下了很多隐患.如果是自己的私有业务倒 ...
- 认识Junit基本注解@Before、@After、@Test、@BeforeClass、@AfterClass(转)
一.unit中集中基本注解,是必须掌握的. @BeforeClass – 表示在类中的任意public static void方法执行之前执行 @AfterClass – 表示在类中的任意public ...
- SpringCloud(2)---SpringCloud入门篇
SpringCloud理解篇 一.微服务概述 1.什么是微服务 目前的微服务并没有一个统一的标准,一般是以业务来划分将传统的一站式应用,拆分成一个个的服务,彻底去耦合,一个微服务就是单功能业务,只做一 ...
- MySQL 索引及查询优化总结
本文由云+社区发表 文章<MySQL查询分析>讲述了使用MySQL慢查询和explain命令来定位mysql性能瓶颈的方法,定位出性能瓶颈的sql语句后,则需要对低效的sql语句进行优化. ...
- Java多线程父子线程关系 多线程中篇(六)
有的时候对于Java多线程,我们会听到“父线程.子线程”的概念. 严格的说,Java中不存在实质上的父子关系 没有方法可以获取一个线程的父线程,也没有方法可以获取一个线程所有的子线程 子线程的消亡与父 ...