Fragment总结

      继续写关于Fragment方面的东西。

1.使用Fragment的意义

      在Activity对应的界面中,如果没有Fragment的话,那么,界面元素是一个View(Layout中包含其他View)。有了Fragment之后,那么Activity

对应的界面中,界面元素有了Fragment(Fragment包含自己的界面,并且逻辑是自己控制的,通常是不与宿主Activity的界面控制逻辑耦合的)。

      其实,说到底,就是模块化。

      在界面中实现模块的方式有:1.通过include的方式,包含一块界面(但是控制逻辑,是要有Activity来实现的)。2.通过Fragment的方式,包含

一块界面,并且该块界面的控制逻辑是由它自己管理的。

      所以,Fragment的意义,就是,让界面模块化,并且界面控制逻辑模块化。

      所以,你的Fragment如果写得模块化程度高,也就是与宿主Activity,或者其他Fragment耦合程度低,那么,你可以将该Fragment所表示的界面及

控制逻辑,方便的搬到任何界面中去。

     注意:Fragment也是可以没有界面的。

2.Fragment的创建及使用

      与Activity的创建类似。创建一个类,它继承Fragment,然后实现必须实现的几个回调方法,如此就创建了一个Fragment。

必须实现的几个回调方法是:

1).onCreate()----这个是用来初始化各种数据的。当然,如果你没有要初始化的数据,这个略掉也是可以的。

2).onCreateView()---这个返回的View就是Fragment对应的界面;如果返回Null,则表示该Fragment没有界面。另外,在重写这个方法时要注意的事项:

onCreateView(LayoutInflater inflater, ViewGroup container, Bundle data)

A.如果你在生成View的时候,是使用这种方式的:View view = inflater.inflate(R.layout.fragment_ui, null);没有指定container,

那么,你就可以动态的将该Fragment添加到你想要添加的界面中去。比如,添加到R.id.fragment中去,R.id.fragment就是container的ID。

getFragmentManager().beginTransaction().add(R.id.fragment, f).commit();

 

B.如果你在生成View的时候,是使用这种方式的:View view = inflater.inflate(R.layout.fragment_ui, container);指定了container。

那么,你就只能,通过fragment标签的方式将Fragment添加到界面去。比如:

<fragment
     android:id="@+id/simpleFragment"
     android:name="com.containertest.fragment.SimpleFragment"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" />

原因是:

对于A,因为,如果你指定了Fragment界面的container,那么,你就不可以在代码中再次指定(每次add的时候,第一个参数就是container的id)。因为,你已经指定了Fragment的

container了,它就是onCreateView中的参数。

在运行中,会发现这样的问题:

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

实践中发现的。

 

对于B.你指定了container,那么,当你的fragment作为标签添加到某个界面的时候,系统是这样执行的:

在加载界面的时候,加载到Fragment标签,它会去找该标签相应的实现类,调用到onCreateView的时候,系统根据当前该标签是属于哪个Parent的下的View,将Parent ViewGroup作为container,作为参数调用onCreateView。

 

3).onPause()----这个,考虑到,你要保存某些数据到文件中去,因为,这个时候过去之后,有可能Fragment就不会再次出现了,销毁了。为了确保用户输入的数据,保存下来了,那么,此时你可以确定那些需要保存的数据,然后,在系统回调该方法的时候执行保存。跟Activity的onPause()作用相同。即使,该Fragment所在的进程,也就是该应用它关闭了,然后,你再次启动包含该Fragment的应用,那么,你还是可以得到你保存过的数据,因为你将数据保存到文件中去了。

---当然,如果你不考虑,那么,这个也可以不用重写。

4).onSaveInstanceState(Bundle data)---这个,与onPause的作用类似。区别是,它的数据是保存到Bundle中去,然后,恢复的时候,是在onCreate(Bundle data)的data中恢复。也就是,这里保存了数据,然后,在onCreate中取回。另外一个关键的区别是:只有当前应用没有关闭的情况下,也就是当前进程下,这个过程才会发生。销毁当前Fragment对象,然后,创建新的Fragment对象,这两个操作都在当前进程中发生,那么,销毁的Fragment对象它的数据可以保存在Bundle中,然后,在新创建的Fragment对象,可以通过Bundle再次取回。

----如果,销毁该Fragment,保存数据到Bundle中,然后,当前进程,也就是当前app关闭了。然后,再次启动该app,那么,数据是不会恢复回来的。也就是,该Bundle的作用范围是当前进程。

----当然,如果你不考虑,这个也可以不用重写。

--------------以上就是关于fragment创建时,通常你要做的事情,其它方面,则根据具体需要来做--------------------------------------------------------------

      Fragment使用方面:

      使用方式:1.动态添加,new一个Fragment对象,然后将它添加到相应的容器中去。2.通过fragment标签添加,固定的方式。在标签中指明对应的实现类便可。

然后就可以了。在onCreateView()中,设定一些界面控制逻辑,这样Fragment就有了相应的界面控制逻辑了。

1.动态添加,new一个Fragment对象,然后将它添加到相应的容器中去,牵涉到的相关内容:

1).你可以动态的添加或者移除,或者更换Fragment,针对某个容器(ViewGroup)。这样的一个或者几个操作,叫做Fragment事务,FragmentTransaction.

FragmentTransaction事务对象,提供了add,remove,replace这三个操作。事务要提交,然后,才会生效。

2).Fragment要具备Activity回退的效果。场景,有时候,比如,我添加了fragmentA到container中去,然后,我想按下返回按钮,将container的fragmentA退回到fragmentB。效果等同于,按下返回按钮,返回到之前的Activity,只不过是Activity换成fragment。

要实现这种效果,就要在提交事务之前调用addToBackStack(),如此宿主Activity就会为管理该Fragment(其实,每个宿主Activity有一个FragmentManager)。

比如:点击NextFragment按钮,替换为FragmentB;在界面上按下返回按钮,返回到之前的FragmentA

public class MainActivity extends Activity {

    public static final String FragmentBTag = "fragmentB";
    public static final String FragmentATag = "fragmentA";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        inital();
    }

    private void inital() {
        addFragmentA();
        Button nextBtn = (Button) findViewById(R.id.nextFragment);
        nextBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                FragmentTransaction ft = getFragmentManager()
                        .beginTransaction();

                if (getFragmentManager().findFragmentByTag(FragmentBTag) == null) {
                    ft.addToBackStack(null);
                    ft.replace(R.id.container, FragmentB.newInstance(),
                            FragmentBTag).commit();
                }

            }
        });
    }

    private void addFragmentA() {
        FragmentManager fm = getFragmentManager();
        FragmentTransaction ft = fm.beginTransaction();
        ft.addToBackStack(null);
        ft.add(R.id.container, FragmentA.newInstance()).commit();

    }

    @Override
    public void onBackPressed() {
        FragmentManager fm = getFragmentManager();
        if (!fm.popBackStackImmediate()) {
            super.onBackPressed();
        }

    }

}

3.Activity的状态对Fragment的状态的影响

用如下一副图就可以说明:

activity_fragment_lifecycle

--------------以上就是关于Fragment方面的总结----------------------------

总结:

1.Fragment的事务。

2.宿主Activity提供一个回退栈,管理Fragment事务。

3.Activity状态对Fragment状态的影响。

4.Fragment的使用场景。

版权声明:
作者:ttylinux
         
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/ttylinux/p/3776957.html