• Fragment 基础使用及重叠问题


    一 基本使用

    Fragment依附于Activity使用,方面我们在一个页面里面切换显示多屏内容。

    Activity管理Fragment有两种方式,通过FragmentTransacation这个类来管理fragment的显示、隐藏

    1 replace方法

    1 FragmentTransaction transaction = mBaseActivity.getSupportFragmentManager().beginTransaction();
    2 transaction.replace(R.id.fl_container, mCurrent).commit();

    使用这种方法,可以避免出现fragment重叠问题。但每次执行replace时,fragment都会重新走一遍生命周期方法,会造成重复加载数据。不推荐使用。

    2 hide,show,add方法

     1     private void switchFragment(Fragment from, Fragment to) {
     2         if (mCurrent != to) {
     3             mCurrent = to;
     4             FragmentTransaction transaction = mBaseActivity.getSupportFragmentManager().beginTransaction();
     5             // 判断目标fragment是否被add过
     6             if (!to.isAdded()) {
     7                 transaction.hide(from).add(R.id.fl_container, to,to.getClass().getName()).commit();
     8             } else {
     9                 transaction.hide(from).show(to).commit();
    10             }
    11         }
    12     }

    使用这种方法,避免了重新加载数据问题,但是会出现fragment重叠问题。

    原因:当内存不足时,系统会回收宿主Activity,而Fragment实例并没有被一并回收,activity被回收时会主动调用onSaveInstanceState方法,保存视图层(View Hierarchy)及一些activity的数据。

    二 重叠问题

    通过onCreate中的参数savedInstanceState恢复了之前的fragment。此时的FragmentTransaction中的相当于又再次add了fragment进去的,之前保存的fragment也还在。hide()和show()方法对之前保存的fragment已经失效了。之前显示的fragment一直显示,所以出现了重叠的现象。解决方法:

    首先,activity被系统收回,触发onSaveInstanceState(Bundle outState)方法,在outstate里,系统自动保存了fragment数据,手动保存当前显示的fragment索引

    1    private static final String SAVED_CURRENT_ID = "currentId";
    2     private int currentIndex;
    3     @Override
    4     public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
    5         outState.putInt(SAVED_CURRENT_ID, currentIndex);//保存当前显示fragment索引
    6         super.onSaveInstanceState(outState, outPersistentState);
    7     }

    其次,当重新进入activity时,走生命周期方法oncreae(Bundle savedInstanceState),saveInstanceState 包含了fragment数据,以及其他一些view的状态,和我们手动保存的数据,从bundle里取出fragment对象,避免重新实例化fragment,造成视图重叠

     1     @Override
     2     protected void onCreate(Bundle savedInstanceState) {
     3         super.onCreate(savedInstanceState);
     4         setContentView(R.layout.activity_main);
     5         //重启时防止fragment重叠
     6         if (savedInstanceState != null) {
     7             currentIndex = savedInstanceState.getInt(SAVED_CURRENT_ID, 0);
     8             homeFragment = (HomeFragment) getSupportFragmentManager().findFragmentByTag(HomeFragment.class.getName());
     9             newsFragment = (NewsFragment) getSupportFragmentManager().findFragmentByTag(NewsFragment.class.getName());
    10             findFragment = (FindFragment) getSupportFragmentManager().findFragmentByTag(FindFragment.class.getName());
    11             adminFragment = (AdminFragment) getSupportFragmentManager().findFragmentByTag(AdminFragment.class.getName());
    12         } else {
    13             initFragment();
    14         }
    15         intView();
    16     }
    17 
    18     @Override
    19     protected void intView() {
    20         setTitle("主页");
    23 radioGroup = (RadioGroup) findViewById(R.id.rg_main_bottom); 24 radioGroup.setOnCheckedChangeListener(occl); 25 ((RadioButton) radioGroup.getChildAt(currentIndex)).setChecked(true); 26 }

    最后,恢复选中fragment

     1     private RadioGroup.OnCheckedChangeListener occl = new RadioGroup.OnCheckedChangeListener() {
     2 
     3         @Override
     4         public void onCheckedChanged(RadioGroup group, int checkedId) {
     5             switch (checkedId) {
     6                 case R.id.rb_home:
     7                     setTitle("首页");
     8                     currentIndex = 0;
     9                     if (homeFragment == null) {
    10                         homeFragment = HomeFragment.newInstance(null, null);
    11                     }
    12                     switchFragment(mBackHandledFragment, homeFragment);
    13                     break;
    14                 case R.id.rb_news:
    15                     setTitle("新闻");
    16                     currentIndex = 1;
    17                     if (newsFragment == null) {
    18                         newsFragment = NewsFragment.newInstance(null, null);
    19                     }
    20                     switchFragment(mBackHandledFragment, newsFragment);
    21                     break;
    22                 case R.id.rb_find:
    23                     showTabSelectView();
    24                     currentIndex = 2;
    25                     if (findFragment == null) {
    26                         findFragment = FindFragment.newInstance(null, null);
    27                     }
    28                     switchFragment(mBackHandledFragment, findFragment);
    29                     break;
    30                 case R.id.rb_admin:
    31                     setTitle("我的");
    32                     currentIndex = 3;
    33                     if (adminFragment == null) {
    34                         adminFragment = AdminFragment.newInstance(null, null);
    35                     }
    36                     switchFragment(mBackHandledFragment, adminFragment);
    37                     break;
    38             }
    39         }
    40     };
    41 
    43     private void switchFragment(Fragment from, Fragment to) {
    44         FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    45         if (null == from) {
    46             if (mBackHandledFragment != to) {
    47                 mBackHandledFragment = (BackHandledFragment) to;
    48                 if (!to.isAdded()) {
    49                     transaction.add(R.id.frameLayout_container, to, to.getClass().getName()).commit();
    50                 } else {
    51                     transaction.show(to).commit();
    52                 }
    53             }
    54         } else {
    55             if (mBackHandledFragment != to) {
    56                 mBackHandledFragment = (BackHandledFragment) to;
    57                 // 判断目标fragment是否被add过
    58                 if (!to.isAdded()) {
    59                     transaction.hide(from).add(R.id.frameLayout_container, to, to.getClass().getName()).commit();
    60                 } else {
    61                     transaction.hide(from).show(to).commit();
    62                 }
    63             }
    64         }
    65     }
  • 相关阅读:
    Seaborn学习笔记2
    Seaborn学习笔记1
    HTML学习笔记4
    HTML学习笔记3
    HTML学习笔记2

    指针与引用
    函数
    字符串
    C++简易
  • 原文地址:https://www.cnblogs.com/suiyilaile/p/9084279.html
Copyright © 2020-2023  润新知