Fragment的使用

来源:互联网 发布:计算机编程语言 知乎 编辑:程序博客网 时间:2024/05/29 18:34

Fragment的使用

为了让界面可以在平板上更好地展示,Android在3.0版本引入了Fragment(碎片)功能,它非常类似于Activity,可以像 Activity一样包含布局。Fragment通常是嵌套在Activity中使用的。

 

1.Fragment初探

Fragment可以让我们很好地利用手机的空间,例如,在一个竖屏的平板或者手机上,Fragment1可能在这个Activity上,Fragment可能在另一个Activity上;在一个横屏的手机或平板上,Fragment1和Fragment2可以在同一个Activity上。

  如何使用Fraagment呢?因为Fragment是3.0版本后引入的,所以低于3.0的版本要导入android-support-v4.jar版本的jar包才能使用Fragment。

 

2.动态添加Fragment

 (1)动态添加Fragment的步骤

    1)获取到FragmentManager,在Activity中可以直接通过getFragmentManager得到;

2)开启一个事务,通过调用beginTransaction方法开启;

3)向容器内加入Fragment,一般使用replace方法实现,需要传入容器的id和Fragment的对象实例。

4)提交事务,调用commit方法提交。

在Activity中添加如下代码就可以用Fragment替换布局容器,如下所示:

  MyFragment myFragment = new MyFragment();

  getSupportFragmentManager().beginTransaction().replace(R.id.ll_main_content, myFragment).commit();

 

3.Fragment的生命周期

  (1)和Activity一样,fragment也有自己的生命周期,理解其生命周期很重要。Fragment的生命周期函数包括:

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {   

        Log.d(TAG, "onCreateView");   

        return inflater.inflate(R.layout.fragment1, container, false);   

}   

@Override 

publicvoid onAttach(Activity activity) {   

        super.onAttach(activity);   

        Log.d(TAG, "onAttach");   

    }   

10 @Override 

11 publicvoid onCreate(Bundle savedInstanceState) {   

12         super.onCreate(savedInstanceState);   

13         Log.d(TAG, "onCreate");   

14 }   

15 @Override 

16 publicvoid onActivityCreated(Bundle savedInstanceState) {   

17         super.onActivityCreated(savedInstanceState);   

18         Log.d(TAG, "onActivityCreated");   

19 }   

20 @Override 

21 publicvoid onStart() {   

22         super.onStart();   

23         Log.d(TAG, "onStart");   

24 }   

25 @Override 

26 publicvoid onResume() {   

27         super.onResume();   

28         Log.d(TAG, "onResume");   

29 }   

30 @Override 

31 publicvoid onPause() {   

32         super.onPause();   

33         Log.d(TAG, "onPause");   

34 }   

35 @Override 

36 publicvoid onStop() {   

37         super.onStop();   

38         Log.d(TAG, "onStop");   

39 }   

40 @Override 

41 publicvoid onDestroyView() {   

42 super.onDestroyView();   

43         Log.d(TAG, "onDestroyView");   

44     }   

45 @Override 

46 publicvoid onDestroy() {   

47         super.onDestroy();   

48         Log.d(TAG, "onDestroy");   

49  }   

50 @Override 

51 publicvoid onDetach() {   

52         super.onDetach();   

53         Log.d(TAG, "onDetach");   

54 }   

 

运行程序,生命周期函数调用顺序:onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart -> onResume

点击home键,先后调用:onPause -> onStop

重新进入程序,先后调用:onStart -> onResume

然后点击back键退出程序,先后调用:onPause -> onStop -> onDestroyView -> onDestroy -> onDetach

  (2)Fragment的生命周期函数同Activity很相似,介绍一下Activity中没有的新方法:

      1)onAttach方法:Fragment和Activity建立关联的时候调用;

      2)onCreateView方法:为Fragment加载布局时调用;

   3)onActivityCreated方法:当Activity中的onCreate方法执行完后调用;

 4)onDeatroyView方法:Fragment中的布局被移除时调用;

 5)onDetach方法:Fragment和Activity解除关联的时候调用。

 

4.Fragment之间进行通信

通常情况下,Activity会包含多个Fragment,这时多个Fragment之间如何进行通信呢?例如,如何在一个Fragment中去访问另一个Fragment的视图。

Fragment2.java:

TextView tv = (TextView)getActivity().findViewById(R.id.tv_fragment1_text); 

 

这里通过getActivity方法,可以让Fragment获取到关联的Activity,然后调用Activity的findViewbyId方法,就可以获取到和这个Activity关联的其他Fragment的视图了。

 

5.多个Fragment切换时不重新实例化(replace/add  是否添加到stack中)

在项目中进行Fragment切换时,一直都是用replace()方法来替换Fragment,如:

MyFragment myFragment = new MyFragment();

getSupportManager().beginTrasaction().setCustomAnimations(R.anim.fade_in, R.anim.slide_out).replace(R.id.ll_main_content, myFragment).commit();

 

上述用replace方法替换,Fragment每次都会重新实例化,重新加载数据,这样非常消耗性能和用户的数据量。如何让多个Fragment彼此切换时不重新实例化呢?

正确的切换方式是add(),切换时时是hide()隐藏,再add()另一个Fragement;再次切换时,就只需要hide()当前,show()另一个,这样就能做到多个Fragment切换时不实例化,如:

//显示fragment1

if (当前选中的index != 正要切换的下标i) {

if (fragment1 == null) {    fragment1 = new MyFragment();    }

if (index == 1) { getSupportFragmentManager().beginTransaction().hide(fragment1).commitAllowingStateLoss();

 

else if (index == 2) { getSupportFragmentManager().beginTransaction().hide(fragment2).commitAllowingStateLoss();

}

if (fragment1.isAdded()) {  //已经添加过了,直接show getSupportFragmentManager().beginTransaction().show(fragment1).commitAllowingStateLoss();

 

else {   //没有添加就add

getSupportFragmentManager().beginTransaction().add(R.id.linear_main, fragment1).commitAllowingStateLoss();

}

}

 

上述详见http://www.yrom.net/blog/2013/03/10/fragment-switch-not-restart/

 

注:

Replace和add的区别:

add 是吧一个fragment添加到一个容器container里,replace是先remove掉所有相同id的所有fragment,然后再add当前的这个fragment。

 

6.Fragment返回栈的管理

 

将Fragment添加到返回栈中,假设现在有两个Fragment: Fragment01和Fragment02,现在从Fragment01跳转到Fragment02,然后按Back键,发现程序直接退出了,二人不是返回到Fragment01。如果现在想实现以下功能:从Fragment01的界面跳转到Fragment02,然后按返回键,会返回到Fragment01,如何实现,就需要利用返回栈的知识。

 

FragmentTransaction提供了一个addToBackStack()方法,可以将一个事务添加到返回栈中。

getSupportFragmentManager().beginTransaction().add(R.id.linear_main, fragment1).addToBackStack(null).commitAllowingStateLoss();

 

0 0
原创粉丝点击