• 【转】 Pro Android学习笔记(四一):Fragment(6):数据保留


    目录(?)[-]

    1. 通过fragment参数实现数据保留
      1. 对TitleFragment进行修改
      2. 对DetailActivity进行修改
    2. 通过savedInstanceState进行数据保留
    3. 保留fragment实例

    在横屏竖屏切换时,activity将保留状态,退出,然后重新创建。我们今天要解决的问题是,通过fragment,横竖屏切换时,如何保留关键数据。在Fragment的生命周期中的Bundle savedInstanceState是用于保存fragment状态,此外,还可以使用fragment参数进行数据的保留。

    通过fragment参数实现数据保留

    当屏幕进行切换时,activity将退出,重新create,我们希望屏幕转向时,仍能看到原来的数据。诚然有很多方式,例如在app中,通过其他静态参数保留,通过本地存储保留等等。我们可以简单地利用fragment的参数进行关键数据保留。本例中的关键数据为书面的序号,故需要TitleFragment将其作为参数进行保存,系统在自动保存fragment的参数,在下次create时获取。

    对TitleFragment进行修改

    public class TitleFragment extends ListFragment{ 
        private int mCurCheckPosition = -1; 
       … 略 …  

        public void onListItemClick(ListView l, View v, int position, long id) {  
            mCurCheckPosition = position; 
            myActivity.showDetails(mCurCheckPosition); 
            Bundle b = getArguments(); 
            if(b != null){ 
                b.putInt("index", mCurCheckPosition);  //更新参数
            } 
        }      
          
        public void onInflate(Activity activity, AttributeSet attrs, Bundle savedInstanceState) {
           //如果参数不存在,设置参数,如果参数存在,获取参数。    
            Bundle b = getArguments(); 
            if(b != null){ 
                mCurCheckPosition = b.getInt("index", -1);  
            }else{ 
                b = new Bundle(); 
                b.putInt("index", mCurCheckPosition); 
                setArguments(b); 
            } 
            super.onInflate(activity, attrs, savedInstanceState);
        } 
        

    至此,在横屏切换到竖屏中,我们可以直接进入相应的书目简介内容中。在切换时,系统在一个保存状态(saved state)中重新创建(re-create) fragment,这时缺省的构造函数函数被调用,带有初始化参数bundle。此外,对于参数设置,如本例设置“index”参数应在onAttach之前进行,即在onInfalte状态或构造函数中进行,注意,不是每个flagment都有onInfalte状态。

    对DetailActivity进行修改

    通过参数保存,从横屏到竖屏符合预期,从竖屏(目录)切换到横屏符合预期,但是从竖屏(简介)切换到横屏不符合预期,只是将DetailsActivity转向,对DetailsActivity的修改如下。当检测到屏幕为横屏时退出即可。

    public class DetailActivity extends Activity{ 
        @Override 
        protected void onCreate(Bundle bundle) { 
            super.onCreate(bundle); 
            if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE ){
                finish(); 
                return; 
            } 
                
            Intent intent = getIntent(); 
            if(intent == null){ 
                finish(); 
                return; 
            }          
            DetailFragment detail = DetailFragment.newInstance(intent.getExtras()); 
            getFragmentManager().beginTransaction() 
                .add(android.R.id.content, detail) 
                .commit();        
        } 
    }

    通过savedInstanceState进行数据保留

    在横竖屏切换中,在onPause()状态后,fragment的生命周期会进入onSaveInstanceState()状态,我们可以在此状态中将所需的数据让如fragment的状态(bundle)中保持,如下所示,我们以保存书名信息为例子。当系统认为需要进行状态时会调用onSaveInstanceState(),通常在onPause()后,当也可以发生在onDestroy()之前的其他时间。

        public void onSaveInstanceState(Bundle outState) {
            if(mCurCheckPosition > 0)
                outState.putString("Book", BooksInfo.TITLES[mCurCheckPosition]);
            else
                outState.putString("Book", null);
            super.onSaveInstanceState(outState);
        }

    当fragment重新创建,在若干生命周期状态中都可以读取,例如:

    [java] view plaincopy
     
    1. public void onInflate(Activity activity, AttributeSet attrs,Bundle savedInstanceState) {  
    2.     if(savedInstanceState != null){  
    3.         showInfo("**** book is " + savedInstanceState.getString("Book"));  
    4.     }  
    5.     ... 略 ...  
    6.     super.onInflate(activity, attrs, savedInstanceState);  
    7. }  
    8.   
    9. public void onCreate(Bundle bundle) {  
    10.     super.onCreate(bundle);  
    11.     if(bundle != null){  
    12.         showInfo("**** book is " + bundle.getString("Book"));  
    13.     }  
    14. }  

    保留fragment实例

    在fragment的生命周期图中,有虚线的部分,从onDestroyView回到onCreateView状态,这是保留fragment实例,但测试场景,我没能找到进行验证。下面是保留fragment实例的实现方式:

    [java] view plaincopy
     
    1. public void onCreate(Bundle bundle) {  
    2.     super.onCreate(bundle);  
    3.     setRetainInstance(true);//设置true,表明在存储中保留fragment对象。  
    4. }  

    由于将返回onCreateView()状态,合适的设置位置在onCreate()中。这种情况要求fragment不在back stack中,尤其适合于没有UI的fragment,当activity被destroy并重建时,fragment仍在app中,其onDestroy()以及onCreate()并不会被调用,onDetach()和onAttach()、onActivityCreated()会被调用,因为需要关联到新的activity中。

    本博文涉及的例子代码,可以在Pro Android学习:Fragment中下载。

    相关链接: 我的Android开发相关文章

  • 相关阅读:
    批量渲染烘焙贴图工具
    Reset textruemap _path of ZIP and copy allfiles to samepackage
    剔除数组中的相同元素
    选择样条曲线的OPEN 点
    帮朋友修改的小工具
    MAX脚本规范
    jQuery牛人
    最近在连远程的时候,粘贴数据库中数据信息时,为什么会不成功呢
    最近在连远程的时候,粘贴数据库中数据信息时,为什么会不成功呢
    Model层代码自动生成
  • 原文地址:https://www.cnblogs.com/blongfree/p/5047979.html
Copyright © 2020-2023  润新知