Android之Fragment与Activity的那些事儿

一:Fragment

我们需要知道的一点:
所有的Fragment子类都必须包含一个公共的空的构造器。因为在需要的时候,Framework会经常重新实例化Fragment类,在特殊的状态恢复期间,需要能够找到这个构造器来实例化Fragment类。如果空的构造器无效,那么在状态恢复期间会导致运行时异常发生。

所以对于Fragment创建实例的传参操作,官方推荐用setArguments来传递参数,而不要使用构造函数来传参。

因为当设备参数变化时,例如竖屏变成横屏,activity会重新构建,并展示给用户。那么依附该activity的fragment也会被重新构建(反射调用Fragment的无参构造来实例化),原来的fragment的数据都会被丢失。但是通过setArguments设置的bundle参数会被保留下来。

通过setArguments来传入参数实例:

public static Fragment newInstance(String arg){  
                    TestFragment fragment = new TestFragment();  
                    Bundle bundle = new Bundle();  
                    bundle.putString( ARG, arg);  
                    fragment.setArguments(bundle);  
                return fragment;  
        }
@Override  
              public View onCreateView(LayoutInflater inflater, ViewGroup container,  
                    Bundle savedInstanceState) {  
                    View rootView = inflater.inflate(R.layout. fragment_main, container,  false);  
                    TextView tv = (TextView) rootView.findViewById(R.id. tv);  
                    tv.setText(getArguments().getString( ARG));  
                     return rootView;  
             }  

为了掌握Fragment的应用,我们需要了解他的完整生命周期。
->onAttach()
->onCreate()
->onCreateView()
->onActivityCreated()
->onStart()
->onResume()
->onPause()
->onStop
->onDestoryView()
->onDestory()
->onDetach()

1.当fragment被加载的时候
->onAttach()
->onCreate()
->onCreateView()
->onActivityCreated()
->onStart()
->onResume()

2.替换fragment不加入回退栈,或者退出按钮。Fragment会被销毁.
->onPause()
->onStop()
->onDestoryView()
->onDestory()
->onDetach

3.替换fragment加入回退栈,fragment实例不会被销毁,只是销毁视图而已。
->onPause()
->onStop()
->onDestoryView()
此时拿下back按键,fragment会被重新显示
->onCreateView()
->onActivityCreated()
->onStart()
->onResume()

4.Activity启动一个对话框,Activity进入onPause(),fragment也会进入onPause();

5.关闭对话框,activity进入运行状态,fragment也会进入运行状态。onPause()->onResume();fragment并没有重构视图。(当我们不想重构fragment的时候,要保存原来fragment数据的时候,可以先把fragment隐藏,hide(),处于暂停状态)

事务操作:

获取FragmentManage的方式:getFragmentManager() // v4中,getSupportFragmentManager。

transaction.remove() :
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。如果添加到回退栈,则这个Fragment的实例不会销毁,但是它的布局视图会被销毁。

transaction.replace():
使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体。

transaction.hide():
隐藏当前的Fragment,仅仅是设为不可见,实例并不会销毁,Fragment的布局视图也不会销毁。

transaction.show():
显示之前隐藏的Fragment。

transaction.addToBackStack(null):
添加到回退栈。

注意:常用Fragment的哥们,可能会经常遇到这样Activity状态不一致:State loss这样的错误。主要是因为:commit方法一定要在Activity.onSaveInstance()之前调用。

transaction只是记录了从一个状态到另一个状态的变化过程,即比如从FragmentA替换到FragmentB的过程,当通过函数transaction.addToBackStack(null)将这个事务添加到回退栈,则会记录这个事务的状态变化过程,如从FragmentA —>FragmentB,当用户点击手机回退键时,因为transaction的状态变化过程被保存,则可以将事务的状态变化过程还原,即将FragmentB —> FragmentA.
使用:a、比如:我在FragmentA中的EditText填了一些数据,当切换到FragmentB时,如果希望会到A还能看到数据,则适合你的就是hide和show;也就是说,希望保留用户操作的面板,你可以使用hide和show,当然了不要使劲在那new实例,进行下非null判断。
b、再比如:我不希望保留用户操作,你可以使用remove(),然后add();或者使用replace()这个和remove,add是相同的效果。
c、remove和detach有一点细微的区别,在不考虑回退栈的情况下,remove会销毁整个Fragment实例,而detach则只是销毁其视图结构,实例并不会被销毁。那么二者怎么取舍使用呢?如果你的当前Activity一直存在,那么在不希望保留用户操作的时候,你可以优先使用detach。
这里写图片描述

这里写图片描述

二:Activity

Activity生命周期
->onCreate()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestory()

1.打开一个avtivity
onCreate()
->onStart()
->onResume();

2.Back键退出activity
->onPause()
->onStop
->onDestory();

3.Home键切换应用,activity并没有被销毁:
->onPause()
->onStop

4.在回到该activity:
->onRestart()
->onStart()
->onResume();
加入这个页面有edittext,里面手动输入了一些数据,当我们切换回来的时候,数据消失了

上面写的还不够直观,我们直接看图:
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

参考
http://www.cnblogs.com/JohnTsai/p/4052676.html



//当我们按HOME键时,我在onPause方法里,将输入的值赋给mString  
@Override  
protected void onPause() {  
        super.onPause();  
        mString = mEditText.getText().toString(); 
}  
//当按HOME键时,然后再次启动应用时,我们要恢复先前状态  
    @Override  
    protected void onRestart() {  
        super.onRestart();  
        mEditText.setText(mString);  
    } 

onCreate中的savedInstanceState有何具体作用?
在activity不可见,或者失去焦点的时候,都有可能被kill掉。这时候需要一种保存当时状态的机制。就是savedInstanceState。当activity在pause时候,被Kill之前,会调用onSaveInstanceState()来保存当时activity的状态。用来保存信息的对象bundle会传给
onCreate(Bundle savedInstanceState)和onRestoreInstanceState(Bundle savedInstanceState)两个方法。
我们可以这样重写这三个方法:


public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(null != savedInstanceState){
            int IntTest = savedInstanceState.getInt("IntTest");
            String StrTest = savedInstanceState.getString("StrTest");
        }
        setContentView(R.layout.main);
    }

    @Override
    public void onSaveInstanceState(Bundle savedInstanceState) {
      savedInstanceState.putInt("IntTest", 0);
      savedInstanceState.putString("StrTest", "savedInstanceState test");
      super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
      super.onRestoreInstanceState(savedInstanceState);
      int IntTest = savedInstanceState.getInt("IntTest");
      String StrTest = savedInstanceState.getString("StrTest");
    }

那么有什么用处?
savedInstanceState状态这个参数在实现应用中有很大的用途,比如:一个游戏在退出前,保存一下当前游戏运行的状态,当下次开启时能接着上次的继续玩下去。再比如:电子书程序,当一本小说被阅读到第199页后退出了(不管是内存不足还是用户自动关闭程序),当下次打开时,读者可能已忘记了上次已阅读到第几页了,但是,读者想接着上次的读下去。如果采用saveInstallState参数,就很容易解决上述问题。

参考:
http://blog.sina.com.cn/s/blog_7b83134b0101603x.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值