Android实战开发中Fragment你所应该知道的一切

本文出自门心叼龙的博客,转载请注明出处: https://blog.csdn.net/geduo_83/article/details/86559417

1. 请简述Fragment的意义?

1.1 Fragment是Activity界面的一部分,Fragment是依附于Activity之上的;
1.2 Activity是Fragment的基础,Fragment是Activity的延续和发展
1.3 一个Activity可以有多个Fragment,一个Fragment也可以被多个Activity重复使用;
1.4 一个Fragment除了Activity处于onResume状态下,他可以自己灵活的控制自己的生命周期,其他状态下,其生命周期都是由Activity所决定的;
1.5 Fragment的出现增强了UI界面布局的灵活性,可以实现动态的改变UI布局;

2. 将一个Fragment添加到Activity布局的方式有几种?

2.1 通过fragment标签加入(静态加入)
2.2 通过代码动态的加入(动态加入)

3. 简述Fragment生命周期,常用的回调方法有几个?

onActtch:初始化Fragment 事件回调接口
onCreate:初始化参数
onCreateView:为Fragment绑定布局
onViewCreated:进行控件实例化操作
onPause:在用户离开Fragment是所进行的一些数据持久化操作
当Activity的onCreate方法被回调时会导致fragment方法的onAttach()、onCreate()、onCreateView()、onActivityCreate() 被连续回调

4.怎么为Fragment绑定UI布局?

复写onCreateView方法
inflate方法有三个参数

参数1:需要绑定的Layout的资源Id
参数2:绑定Layout布局的父视图
参数3:是否将参数1的Layout资源依附于参数2的ViewGroup之上
注意了:不管参数3是否为true都依附,系统默认已经将Layout插入至ViewGroup上如果为true,将添加一层冗余的视图

5.怎么去管理Fragment?

通过getFragmentManager()方法获取FragmentManager实例
调用findFragmentById()或者findFragmentByTag()方法来获取一个Fragment
调用popBackStack方法将Fragment从后退站中弹出
调用addOnBackChangedListener()方法注册监听器,用于监听后退站的变化

6.执行Fragment的事务,事务有什么特点?

每个事务都表示执行一组变化,这些变化包括add()、remove()、replace()、addToBackStack()、setCustomAnimations、setTransition事务要生效必须调用commit,commit并不会立即执行,只能等待UI主线程空闲时才能执行也可以调用executePendingTransactions立即生效提交事务,commit在调用时机是Activity状态保存之前进行,也就是说如果在离开Activity是进行提交事务的操作,系统就会抛出异常

7.为Activity创建Fragment的事件回调?

7.1Fragment创建一个接口
7.2Activity实现这个接口
7.3在onActtch方法初始化接口

8.在Fragment中创建菜单直接复写onCreateOptionMenu方法可以吗?

不行,必须在onCreate方法是调用setHasOptionsMenu方法才行onOptionItemSelected进行选择回调

9.如何实现多个Fragment之间的灵活切换?

public void switchContent(Fragment from, Fragment to) {
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    if (!to.isAdded()) {
        transaction.hide(from).add(R.id.frame_content, to).commit();
    } else {
        transaction.hide(from).show(to).commit();
   }
}

10. Activity和Fragment 的 onActivityForResult 回调?

10.1 当在Fragment里面调用startActivityForResult的时候 Activity和Fragment里面的onActivityForResult都会回调,只不过Fragment里面回调的requestCode是正确的
10.2 当在Fragment里面调用getActivity().startActivityForResult的时候,就会回调Activity里面的onActivityForResult
10.3 当Fragment存在多层嵌套的情况,内层的Fragment调用startActivityForResult的时候,onActivityForResult方法不回调,此时需要创建一个BaseActivity复写它的onActivityResult方法

public class BaseFragmentActiviy extends FragmentActivity {
 private static final String TAG = "BaseActivity";
 
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  FragmentManager fm = getSupportFragmentManager();
  int index = requestCode >> 16;
  if (index != 0) {
   index--;
   if (fm.getFragments() == null || index < 0
     || index >= fm.getFragments().size()) {
    Log.w(TAG, "Activity result fragment index out of range: 0x"
      + Integer.toHexString(requestCode));
    return;
   }
   Fragment frag = fm.getFragments().get(index);
   if (frag == null) {
    Log.w(TAG, "Activity result no fragment exists for index: 0x"
      + Integer.toHexString(requestCode));
   } else {
    handleResult(frag, requestCode, resultCode, data);
   }
   return;
  }
 
 }
 
 /**
  * 递归调用,对所有子Fragement生效
  * 
  * @param frag
  * @param requestCode
  * @param resultCode
  * @param data
  */
 private void handleResult(Fragment frag, int requestCode, int resultCode,
   Intent data) {
  frag.onActivityResult(requestCode & 0xffff, resultCode, data);
  List<Fragment> frags = frag.getChildFragmentManager().getFragments();
  if (frags != null) {
   for (Fragment f : frags) {
    if (f != null)
     handleResult(f, requestCode, resultCode, data);
   }
  }
 }
10.3.2 启动Activity的时候一定要用根Fragment
/**
  * 得到根Fragment
  * 
  * @return
  */
 private Fragment getRootFragment() {
  Fragment fragment = getParentFragment();
  while (fragment.getParentFragment() != null) {
   fragment = fragment.getParentFragment();
  }
  return fragment;
 
 }
 
 /**
  * 启动Activity
  */
 private void onClickTextViewRemindAdvancetime() {
  Intent intent = new Intent();
  intent.setClass(getActivity(), YourActivity.class);
  intent.putExtra("TAG","TEST"); 
  getRootFragment().startActivityForResult(intent, 1001);
 }

11. Fragment的View重复添加导致的崩溃问题?

如果把该view添加到父view那么也会引起重复添加而导致崩溃

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    if (view == null) {
        view = inflater.inflate(R.layout.dd_fragment_year, container, false);
    }
    
    ViewGroup viewGroup = (ViewGroup) view.getParent();  
    if (viewGroup != null){
        viewGroup.removeView(view);
    } 
    return view;
}

12. Fragment的getActivity方法返回null的原因:

如果系统内存不足、或者切换横竖屏、或者app长时间在后台运行,Activity都可能会被系统回收,但是Fragment并不会随着Activity的回收而被回收,从而导致Fragment丢失对应的Activity。这里,假设我们继承于FragmentActivity的类为MainActivity,其中用到的Fragment为FragmentA。
app发生的变化为:某种原因系统回收MainActivity——FragmentA被保存状态未被回收——再次点击app进入——首先加载的是未被回收的FragmentA的页面——由于MainActivity被回收,系统会重启MainActivity,FragmentA也会被再次加载——页面出现混乱,因为一层未回收的FragmentA覆盖在其上面——(假如FragmentA使用到了getActivity()方法)会报NullPointerException:

方案1:在使用Fragment的Activity中重写onSaveInstanceState方法,将super.onSaveInstanceState(outState)注释掉,让其不再保存Fragment的状态,达到其随着MainActivity一起被回收的效果。
方案2:在再次启动Activity的时候,在onCreate方法中将之前保存过的fragment状态清除,代码示例如下:

if(savedInstanceState!= null){
    String FRAGMENTS_TAG = "android:support:fragments"; 
    savedInstanceState.remove(FRAGMENTS_TAG);
}

方案3:避免使用getActivity方法得到activity,如果确实需要使用上下文,可以写一个类MyApplication继承Application,并且写一个方法getContext(),返回一个Context 对象。代码示例如下:

public class MyApplication extends Application {
    private static Context context;
   @Override
    public void onCreate() {
        super.onCreate();
         context = this;
}
    public static Context getContext() {
        return context;
     }
}

13.ViewPager中Fragment的缓存

当Fragment在Activity中被取消挂载再次挂载的时候Fragment各个生命周期都会重新执行

public class FragmentFound extends Fragment {
        private View view;
        @Override
        public View onCreateView(LayoutInflater inflater,
            @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        if(view == null){
            view = inflater.inflate(R.layout.fragment_found, null);
        }
        ViewGroup parentView = (ViewGroup)view.getParent();
        if(parentView != null){
            parentView.removeView(view);
        }            
        return view;
        }
    }
    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        if(isVisibleToUser){
        //刷新操作
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,013评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,205评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,370评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,168评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,153评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,954评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,271评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,916评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,382评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,877评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,989评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,624评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,209评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,199评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,418评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,401评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,700评论 2 345

推荐阅读更多精彩内容

  • 沉浸在一件自己感兴趣的事情中 即使耗费再多时间再多精力 也会觉得有趣 值得 可是当与不感兴趣的事情打交道时 就变得...
    霜明Christie阅读 161评论 0 0
  • 绝 ...
    菁鹤堂_刘昭川鹤阅读 282评论 4 1