Frament的基本概念和解析

什么是 Fragment?

Fragment 是 android 3.0 后引入的新的 API,翻译成中文的意思是碎片,可以把它看成简单的小型 Activity,又称 Activity 片段,其功能可以适应大屏幕的平板电脑,使用 Fragment 简化大屏的 UI 设计,对ui 组件进行分组、模块化管理,从而更加方便地在运行过程中动态更新 Activity 的用户界面,需要嵌套在 Activity 中使用,虽然拥有自己的生命周期,但还是会受到其所在 Activity 的生命周期的影响.

这样讲可能很抽象,举个例子,我们手机新闻app,点击左边列表右边显示相对应的新闻,就是用了俩个 Fragment 分别显示的,然后装在同一个 Activity 组合起来

下图为 Fragment 生命周期与回调方法
Frament的基本概念和解析_第1张图片

上图方法简单介绍:

OnAttach( ):当该 Fragment 被添加到 Activity 时会回调,且只会回调一次
OnCreate( ):创建 Fragment 时回调,只会回调一次
OnCreateView( ):每次创建,绘制该 Fragment 的 View 组件时回调,会将显示的 View 返回
OnActivityCreate( ):当 Fragment 所在的 Activity 启动完成后回调
OnStart( ):启动 Fragment 时被回调
OnResume( ):恢复 Fragment 时被回调,onStart()方法后一定回调该方法
OnPause( ):暂停 Fragment 时被回调
OnStop( ):停止 Fragment 时被回调
OnDestroyView( ):销毁该 Fragment 所包含的 View 组件时使用
OnDestroy():销毁 Fragment 时调用
OnDetach():将该 Fragment 从 Activity 被删除、替换完成后回调该方法;onDestroy()方法后一定调用该方法且调用一次

相信上面的生命周期图一时半会你也是记不住的,最后就初略地讲下大概流程吧:

①Activity加载Fragment的时候,依次调用下面的方法:

onAttach -> onCreate -> onCreateView -> onActivityCreated -> onStart ->onResume;

②当我们弄出一个悬浮的对话框风格的Activity,或者其他,就是让Fragment所在的Activity可见,但不获得焦点: onPause

③当对话框关闭,Activity又获得了焦点:onResume

④当我们替换Fragment,并调用addToBackStack()将他添加到Back栈中

onPause -> onStop -> onDestoryView

注意,此时的Fragment还没有被销毁哦!!!

⑤当我们按下键盘的回退键,Fragment会再次显示出来:

onCreateView -> onActivityCreated -> onStart -> onResume;

⑥如果我们替换后,在事务commit之前没有调用addToBackStack()方法将Fragment添加到back栈中的话;又或者退出了Activity的话,那么Fragment将会被完全结束,

Fragment会进入销毁状态

onPause -> onStop -> onDestoryView -> onDestory -> onDetach

PS:开发的时候按照需要覆盖对应的方法,一般比较多的是onCreateView()

1) 3.0版本后引入,即minSdk要大于11

2) Fragment 需要嵌套在 Activity 中使用,当然也可以嵌套到另外一个Fragment中,但这个被嵌套的 Fragment 也是需要嵌套在 Activity 中的,间接地说,Fragment 还是需要嵌套在 Activity 中!!受寄主 Activity 的生命周期影响,当然他也有自己的生命周期!另外不建议在 Fragment 里面嵌套Fragment

因为嵌套在里面的Fragment生命周期不可控!!!

3)官方文档说创建Fragment时至少需要实现三个方法:onCreate( ),onCreateView( ),OnPause( );

不过貌似只写一个onCreateView也是可以的…

4) Fragment 的生命周期和 Activity 有点类似:三种状态:

Resumed:在允许中的Fragment可见 Paused:所在Activity可见,但是得不到焦点

Stoped:

①调用addToBackStack(),Fragment被添加到Bcak栈

②该Activity转向后台,或者该Fragment被替换/删除

ps:停止状态的fragment仍然活着(所有状态和成员信息被系统保持着),然而,它对用户

不再可见,并且如果activity被干掉,他也会被干掉.

5)Fragment的子类有:

对话框: DialogFragment 列表: ListFragment

选项设置: PreferenceFragment WebView 界面: WebViewFragment

问题来了,如何创建 Fragment?

①静态添加Fragment
step 1:定义Fragment的布局,就是fragment显示内容的

step 2:自定义一个Fragment类,需要继承Fragment或者他的子类,重写onCreateView()方法,在该方法中调用:inflater.inflate()方法加载Fragment的布局文件,接着返回加载的view对象

   public class Fragmentone extends Fragment {
        @Override
        public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {

                    View view = inflater.inflate(R.layout.fragment1,container,false);
                    return view;
        }
    }

参数依次是:要加载的fragment布局;加载的fragment所在的父ViewGroup;而第三个参数则是:是否将父ViewGroup添加到布局文件的根视图上,但是这样可能会产生一个多余的ViewGroup对象;使用false则显示第一个参数,这里使用 false.

另外inflate方法还有其他的形式,一种典型的就是直接inflate(要显示布局,null),如果使用这种的话:item布局中的根视图的 layout_XX属性 会被忽略掉,然后设置成默认的包裹内容方式,所以还是建议使用三个参数的inflate()吧!

step 3:在需要加载Fragment的Activity对应的布局文件中添加fragment的标签,
记住,name属性是全限定类名哦,就是要包含Fragment的包名,如:

<fragment
    android:id="@+id/fragment1"
    android:name="com.jay.example.fragmentdemo.Fragmentone"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="1" />

**step 4:**Activity在onCreate( )方法中调用setContentView()加载布局文件即可!

②动态添加Fragment
step 1:调用getFragmentManager获得FragmentManager对象fm

step 2.fm调用beginTransaction( )方法获得Fragment事务对象bt

**step 3:**bt调用add( )添加或者relpace( )替换Fragment,参数都是一样的

第一个参数是要传入的容器,第二个参数是Fragment对象

step 4:最后还需要调用bt.commit( )提交事务,除了add和replace方法外

还有个remove移除Fragment的方法,同样也是需要commit的!

Fragment与Activity的交互

①组件获取:
Fragment获得Activity中的组件:

getActivity().findViewById(R.id.list)

Activity获得Fragment中的组件(根据id和tag都可以):

getFragmentManager.findFragmentByid(R.id.fragment1);

②数据传递
1.Activit传递数据给Fragment:
在Activity中创建Bundle数据包,调用Fragment实例的setArguments(bundle)

从而将Bundle数据包传给Fragment,然后Fragment中调用getArguments获得

Bundle对象,然后进行解析就可以了

2.Fragment传递数据给Activity
在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,

Fragment就可以通过回调接口传数据了,回调,相信很多人都知道是什么玩意,这里就写下局部代码吧,相信读者一看就懂的了:

step 1:定义一个回调接口:(Fragment中)

/*接口*/  
   public interface CallBack{  
       /*定义一个获取信息的方法*/  
       public void getResult(String result);  
   }  

step 2:接口回调(fragment中)

/*接口回调*/  
    public void getData(CallBack callBack){  
        /*获取文本框的信息,当然你也可以传其他类型的参数,看需求咯*/  
        String msg = editText.getText().toString();  
        callBack.getResult(msg);  
    }  

step 3:使用接口回调方法读数据(Activity中)

/* 使用接口回调的方法获取数据 */  
leftFragment.getData(new CallBack() {  
 @Override  
       public void getResult(String result) {              /*打印信息*/  
            Toast.makeText(MainActivity.this, "-->>" + result, 1).show();  
            }
        });  

总结来说,就是

->在Fragment定义一个接口,接口中定义抽象方法,你要传什么类型的数据

参数就设置为什么类型;

->接着还有写一个调用接口中的抽象方法,把要传递的数据传过去

->再接着就是Activity了,调用Fragment提供的那个方法,然后重写抽象方法的时候进行数据

的读取就可以了!!!

3.Fragment与Fragment传数据

其实这很简单,找到要接受数据的fragment对象,直接调用setArguments传数据进去就可以了

通常的话是replace时,即fragment跳转的时候传数据的,那么只需要在初始化要跳转的Fragment

后调用他的setArguments方法传入数据即可!

大概代码如下:

FragmentManager fManager = getSupportFragmentManager( );
FragmentTransaction fTransaction = fManager.beginTransaction();
Fragmentthree t1 = new Fragmentthree();
Fragmenttwo t2 = new Fragmenttwo();
Bundle bundle = new Bundle();
bundle.putString("key",id);
t2.setArguments(bundle); 
fTransaction.add(R.id.fragmentRoot, t2, "~~~"); 
fTransaction.addToBackStack(t1); 
fTransaction.commit(); 

如果是两个Fragment需要即时传数据,而非跳转的话,就需要先在Activity获得f1传过来的数据,再传

到f2了

Fragment管理与Fragment事务:

①管理:
Activity管理Fragment主要依靠FragmentManager可以调用findFragmentById( )获取指定的fragment

也可以调用popBackStack( )方法弹出后台Fragment;也可以调用addToBackStack(null)加入栈

或者监听后台栈的变化:addOnBackStackChangeListener
②事务
如果是增删替换Fragment的话,则需要借助FragmentTransaction对象;

同时执行Fragment的操作后,记得操作完后再使用commit( )方法提交事务哦!

本文主要借鉴出处:http://www.it165.net/pro/html/201411/26932.html

你可能感兴趣的:(android)