Fragment概述:
API:
http://developer.android.com/guide/components/fragments.html
http://developer.android.com/reference/android/app/Fragment.html
http://developer.android.com/reference/android/support/v4/app/Fragment.html
我们都知道,Android上的界面展示都是通过Activity实现的,Activity实在是太常用了。但是Activity也有它的局限性,同样的界面在手机上显示可能很好看,在平板上就未必了,因为平板的屏幕非常大,手机的界面放在平板上可能会有过分被拉长、控件间距过大等情况。这个时候更好的体验效果是在Activity中嵌入”小Activity”,然后每个”小Activity”又可以拥有自己的布局。因此,我们今天的主角Fragment登场了。Fragment简化了大屏幕UI的设计,它不需要开发者管理包含关系的复杂变化,开发者使用Fragment对UI进行分组重用、模块化管理,可以更方便地在运行过程中动态更新Activity的用户界面。
Fragment是Android honeycomb 3.0新增的概念,Fragment名为碎片不过却和Activity十分相似。Fragment用来描述一些行为或一部分用户界面在一个Activity中,Fragment有如下特征:
Fragment可调用getActivity()方法获取它所在的Activity,Activity可调用FragmentManager的findFragmentById()或fingFragmentByTag()方法来获取Fragment。
在Activity运行过程中,可调用FragmentManager的add()、remove()、replace()方法动态的添加、删除或替换Fragment。
你可以合并多个Fragment在一个单独的activity中建立多个UI面板,同时重用Fragment在多个Activity中.你可以认为Fragment作为一个Activity中的一节模块 。
Fragment有自己的生命周期,接收自己的输入事件。
例如在平板上新闻浏览界面,Activity嵌套两个Fragment,左边FragmentA显示新闻列表,右边FragmentB显示新闻内容,当用户单击左边的标题是右边显示相应的新闻。
在手机上运行,可以改为使用两个Activity:ActivityA包含FragmentA,ActivityB包含FragmentB,如下图:
2个Jar包中Fragment的区别:
Fragment是在3.0版本引入的,如果你使用的是3.0之前的系统,需要先导入android-support-v4的jar包才能使用Fragment功能。2个Jar包中的Fragment是有区别的。
区别:
android.app.Fragment兼容的最低版本是 android:minSdkVersion=”11”,即android3.0版
android.support.v4.app.Fragment兼容的最低版本是 android:minSdkVersion=”4”即1.6版
编码中的用法不一样
如果使用v4包中的Fragment,包含它的Activity要用FragmentActivity
如果使用v4包中的Fragment,在获取FragmentManager的时候要用getSupportFragmentManager,FragmentManager、FragmentTransaction都是v4包中的类
使用:
要使用Fragment,可以通过继承Fragmnet类来创建你的Fragment。在该类中重写父类定义好的方法,以便加强你的Fragment UI,初始化Fragment相关变量,从而完成Fragment的功能。
在大多数情况下需要给你的Fragment定制一个UI,也可以为Activity创建一个没有UI,只提供后台行为的Fragment
Fragment包含到Activity中有2中方式,分别来实现以下这种效果:
1.通过activity的xml布局添加,必须申明name属性,指定相应 Fragment
Activity的布局
<fragment
android:id="@+id/leftFragment"
android:name="com.example.fragment_less01.fragment.LeftFragment"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
/>
Fragment的布局只是一个有背景色的LinearLayout,在Fragment的onCreateView()方法中返回一个View即是用户看到的UI:
public class LeftFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
//通过View可以拿到其他控件
View view = inflater.inflate(R.layout.fragment_left, container,false);
return view;
}
}
android.jar中的Fragment onCreateView()方法中
return inflater.inflate(R.layout.fragment_right, null);这么导入会报错。注意,不是三个参数的,添加、删除获取替换的时候,有时会报错
inflate 方法
通过 sdk 的 api 文档,可以知道该方法有以下几种过载形式,返回值均是 View 对象,如下:
a.public View inflate (int resource, ViewGroup root)
b.public View inflate (XmlPullParser parser, ViewGroup root)
c.public View inflate (XmlPullParser parser, ViewGroup root, boolean attachToRoot)
d.public View inflate (int resource, ViewGroup root, boolean attachToRoot)
a:
public View inflate (int resource, ViewGroup root)
reSource:View的layout的ID
root:如果为null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
b:
public View inflate ( XmlPullParser parser, ViewGroup root)
parser:你需要解析xml的解析接口
root:如果null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
c:
public View inflate ( XmlPullParser parser, ViewGroup root, boolean attachToRoot)
parser:你需要解析View的xml的解析接口
root:如果null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
attachToRoot:
ture:也就将此解析的xml作为View根
fase:则为默认的xml,做为根视图View
d:
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
resource:View的layout的ID
root:如果null,则将此View作为根,此时既可以应用此View中的其他控件了。
如果!null, 则将默认的layout作为View的根。
attachToRoot:
ture:也就将此解析的xml作为View根
fase:则为默认的xml,做为根视图View
2.通过Java代码动态创建
add()方法添加
Fragment的布局、代码还是上面的,Activity的xml布局:
<FrameLayout
android:id="@+id/leftFrameLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >
</FrameLayout>
<FrameLayout
android:id="@+id/rightFrameLayout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" >
</FrameLayout>
Activity中:
getFragmentManager().beginTransaction()
.add(R.id.leftFrameLayout, new LeftFragment())
.add(R.id.rightFrameLayout, new RightFragment())
.commit();
这样既可实现上面的效果。
inflater.inflate(R.layout.fragment_left, container);报错
Fragment的替换和移除:
replace()、remove()方法实现,替换后会重新运行一下Fragment的生命周期
有2个背景色不同的FragmentA、FragmentB,刚开始的时候在Activity中显示FragmentA
点击替换后显示FragmentB
Fragment的布局和代码比较简单,主要贴下Activity中的代码:
刚开始的时候显示FragmentA:
fragmentA = new FragmentA();
getFragmentManager().beginTransaction().add(R.id.content, fragmentA).commit();
点击替换处:
//add按返回键时能回到原来的状态 getFragmentManager().beginTransaction().replace(R.id.content, new FragmentB()).addToBackStack(null).commit();
移除处:只能移除指定的Fragment,其他的没效果
getFragmentManager().beginTransaction().remove(fragmentA).commit();
addToBackStack(null)添加原来的状态到栈中,按返回键时能回到原来的状态
Fragment的生命周期:
按照顺序执行的,和Activity类似,只不过多了几个返回、销毁、判断和activity链接的状态的方法:
有几个Activity中没有的新方法,这里重点介绍一下:
onAttach方法:Fragment和Activity建立关联的时候调用。
onCreateView方法:为Fragment加载布局时调用,返回一个视图。
onActivityCreated方法:当Activity中的onCreate方法执行完后调用。
onDestroyView方法:Fragment中的布局被移除时调用。
onDetach方法:Fragment和Activity解除关联的时候调用。