首页 > 代码库 > Fragment小结

Fragment小结

Fragment是Android3.0之后增加的新特性,通常人们叫它碎片。可是,我认为把它理解成一个View模块比較好,尽管它不是继承自View。假设阅读过源代码就知道它是内置View对象从而实现View的特性。在设计模式里面通常说到,扩展一个类的方式有2种,第一就是类继承,第二就是对象组合,而开发经验告诉我们。要多用对象组合。所以Fragment是直接继承Object,组合View来实现View的特性的。

类继承:

这里先看一下Fragment的类继承结构:

技术分享技术分享

生命周期:

Fragment与Activity一样具有生命周期,例如以下:

技术分享

技术分享

而Fragment的生命周期是附着在使用Fragment的Activity的生命周期之上。这里有个图片来比較下:

技术分享

技术分享

源代码分析:

Fragment.java位于SDK的android.app包下,通过查看源代码,能够看到Fragment的实现方式是组合View对象和ViewGroup对象。在Fragment还有startActivity和startActivityFroResult方法,是不是跟Activity非常像?!在使用Fragment的时候一般要实现2个生命周期方法onCreate和onPause,方便保存数据,在重写onCreateView时,能够向ViewGroup对象container中加入某个布局文件代表的View。形如return  inflater.inflate(R.layout.yourlayout,container, false);


Fragment的基本运用

分为布局文件里使用Fragment和在程序中动态加入Fragment

布局文件里使用Fragment

第一步:为Fragment指定一个布局文件。例如以下fragmentlayout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
</RelativeLayout>

第二步:自己写一个类MyFragment继承Fragment类

package com.example.myfragmentlayout;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MyFragment extends Fragment{
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragmentlayout, container, false);
	}
}

重写onCreateView方法。返回自定义的Fragment的layout。这里注意onCreateView方法的參数ViewGroup对象!

特别注意。

第三步:在主Activity的布局文件activity_main.xml中这样写道

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <fragment
        android:name="com.example.myfragmentlayout.MyFragment"
        android:tag="dxd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
</RelativeLayout>

这里务必为fragment指定一个tag或是id属性。!

不然执行会出错。


在程序中动态加入Fragment

还记的重写Fragment中的onCreateView方法中的第二个參数吧,是ViewGroup对象。说明Fragment是被加入到ViewGroup对象中去的。从SDK文档中能够看到ViewGroup的子类是非常多的,这里截个图

技术分享

技术分享

有了这个基础。我们在程序中动态加入Fragment.

前一二步都跟在布局文件里加入Fragment一样的,仅仅有在主Activity的layout文件里指定Fragment的方式不一样,这里我们指定的是一个ViewGroup子类。

第3步

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <FrameLayout
        android:id="@+id/framelayout"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

这里定义的是FrameLayout对象,它是ViewGroup的子类,它作为一个容器把Fragment加入进去。

那么在程序中应该如何去加入呢?

package com.example.myfragmentlayout;

import android.app.Activity;
import android.app.FragmentTransaction;
import android.os.Bundle;

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		MyFragment fragment = new MyFragment();
		FragmentTransaction ft = getFragmentManager().beginTransaction() ;
		ft.add(R.id.framelayout, fragment);
		ft.commit() ;
	}
}

从代码中能够看到,是将fragment对象增加到FrameLayout中去。

最后别忘了commit提交。这里必须注意了。对于同一个FragmentTransaction对象仅仅能提交一次!!

使用FragmentTransaction时须要多注意一下。

由此我们能够想象到。我们能够依据不同的需求选择适当的容器来装Fragment,如ScrollView,LinearLayout等

 

         假设你通过继承LinearLayout来自己定义过控件,那么你肯定对Fragment有非常似成相识的感觉。当你继承LinearLayout时须要实现3个构造方法。在这3个构造方法中,你通过LayoutInflater将layout布局文件转换成View,然后为这个View赋予各种监听方法和事件响应。

反过来思考一下Fragment是不是这样实现的呢?当我们继承Fragment时,我们须要实现onCreateView方法,该方法中就是通过LayoutInflater对象将layout布局文件转换成View。然后为这个View加入各种响应时间和时间响应,最后加入到ViewGroup的子类中去。

 

Fragment的事务处理

         Fragment的事物处理是通过FragmentTransaction来实现的,它是通过FragmentManager得到的。这里说一下它几个经常使用的方法:

add :向某个ViewGroup容器中加入Fragment对象

hide:隐藏某个Fragment。让其不可见。

remove:移除某个Fragment

show:显示某个Fragment

setCustomAnimations:指定Fragment切换时的动画

commit:提交,同一个FragmentTransaction仅仅能commit一次,不然会出错。

 

Fragment的综合应用:

模仿手机QQ主界面的4个视图。详情请见某大神的总结:http://blog.csdn.net/guolin_blog/article/details/13171191

Fragment小结