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     }

原文地址:https://www.cnblogs.com/suiyilaile/p/9084279.html

时间: 2024-08-03 22:39:34

Fragment 基础使用及重叠问题的相关文章

Fragment基础操作

Fragment和Activity类似,同样是具备UI的属性:也就是都能用于规划UI布局... Building a Dynamic UI with Fragments --> Fragments具备有动态UI的属性.为了在Android上为用户提供动态的.多窗口的交互体验,我们需要将UI组件和Activity操作封装成模块进行使用,使得我们可以在activity中对这些模块进行切入切出操作.可以用Fragment来创建这些模块,Fragment就像一个嵌套的activity,拥有自己的布局(l

Fragment基础----信息传递

如何通过activity来访问fragment的信息呢,我们可以通过一个实例来了解. 使用两个Fragment和一个activity管理 效果图: 第一个fragment来表示输入框 第二个fragment表示listview内容 最终由activity来控制两个fragment. 实现方法: fragment与其附着的activity之间的通讯最佳方式: 1, 在发起事件的fragment中定义一个接口,借口中声明你的方法 2,在onattach中要求activity实现该接口 3,在acti

ViewPager+Fragment基础

ViewPager+Fragment MainActivity.java package wuxiaocheng.cn.activity; import android.app.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.sup

android之Fragment基础详解(一)

一.Fragment的设计哲学 Android在3.0中引入了fragments的概念,主要目的是用在大屏幕设备上--例如平板电脑上,支持更加动态和灵活的UI设计.平板电脑的屏幕比手机的大得多,有更多的空间来放更多的UI组件,并且这些组件之间会产生更多的交互. 针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以适应平板神马超级大屏的.难道无法做到一个App可以同时适应手机和平板么,当然了,必须有啊.Fragment的出现就是为了解决这样的问题.你可以把Frag

Fragment基础----创建

1,Fragment的目的及应用场景 fragment 是3.0后引入的类,其字面翻译为“碎片”. 目的是将activity划分成许多单元再进行组合,可以根据不同分辨率屏幕,在不同状态下,灵活创建优化UI并提高复用性. 2,Fragment的创建 第一种方式:通过xml标签创建 step 1:创建fragment类继承fragment关系类,其中导包的时候app包为3.0以后使用,v4包可以向下兼容 step 2:在activity的xml文件中添加fragment标签并添加name属性为fra

Fragment基础----生命周期

Fragment生命周期和Activity对比 注意:在一个app的运行期间,前台的activity有时可能会被其他的视图组件打断,然后进入pause状态. 比如打开一个半透膜的activity (比方一个dialog风格的activity),前一个activity就会进入pause.其实这个时候前一个activity是部分可见的,只是被后来的视图组建挡住了而 失去焦点,这种情况下,失去焦点的activity就处于pause状态. 但是,当一个activity被打断,并且完全不可见时(即使没被挡

Fragment基础讲解

//新建一个碎片public class LeftFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 加载一个碎片界面 View view = inflater.inflate(R.layout.leftfragment, container, false); retu

Android Fragment基础

同一个app内的界面切换 用Fragment比较合适,因为Activity比较重量级 Fragment 轻量级,切换灵活 ------------------------------------------- 1. 创建和使用 Fragment 2. Fragment 的生命周期 及相关的实际应用 3. 创建一个带侧边栏的 Activity 以及使用 4. 创建一个 Tabbed Activity 并使用 5. Fragment的使用和状态保存 6. Fragment的横竖屏切换 -------

Fragment学习基础

Fragment的设计哲学: Fragment是从 Android 3.0开始引入的,主要用于大屏幕设备,如平板电脑. 以一个新闻应用在小屏和大屏设备上的设计来阐述Fragment的设计哲学. 对于小屏的手机设备,应该设计为新闻标题列表单独作为一个页面,点击新闻标题进入新闻详细内容页面.如下图所示: 上图就是两个Activity. 对于大屏的平板设备,应该设计为屏幕的左边是一个新闻标题列表,屏幕的右边部分可以用来显示新闻详细内容,点击左边的新闻标题,在右边显示对应的新闻内容.如下图所示: 对于这