全面升级Android面试之fragment面试题集

来源:互联网 发布:a站软件 编辑:程序博客网 时间:2024/06/16 22:14

1.Fragment为什么被称为第五大组件

答:Fragment比Activity更节省内存,其切换模式也更加舒适,使用频率不低于四大组件,且有自己的生命周期,并且必须依付于Activity

2.Activity创建Fragment的方式

静态创建具体步骤
首先我们同样需要注册一个xml文件,然后创建与之对应的java文件,通过onCreatView()的返回方法进行关联,最后我们需要在Activity中进行配置相关参数即在Activity的xml文件中放上fragment的位置。

动态创建具体步骤
(1)创建待添加的碎片实例
(2)获取FragmentManager,在活动中可以直接通过调用 getSupportFragmentManager()方法得到。
(3)开启一个事务,通过调用beginTransaction()方法开启。
(4)向容器内添加或替换碎片,一般使用repalce()方法实现,需要传入容器的id和待添加的碎片实例。
(5)提交事务,调用commit()方法来完成。

3.FragmentPageAdapter和FragmentPageStateAdapter的区别

答:FragmnetPageAdapter在每次切换页面时,只是将Fragment进行分离,适合页面较少的Fragment使用以保存一些内存,对系统内存不会多大影响
FragmentPageStateAdapter在每次切换页面的时候,是将Fragment进行回收,适合页面较多的Fragment使用,这样就不会消耗更多的内存

4Fragment的生命周期

这里写图片描述
首先既然Fragment必须依附于Activity才能存在,我们就来具体分析一下

运行状态
当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态

暂停状态
当一个活动进入暂停状态时(由于另一个未占满屏幕的活动被添加到栈顶),与它相关联的可见碎片就会进入到暂停状态

停止状态
当一个活动进入到停止状态时,与它相关联的碎片就会进入到停止状态,或者通过调用FragmentTransaction的removed(),replace()方法将碎片从活动中移除,但如果在事务提交之前调用addToBackStack()方法,这时碎片就会进入到停止状态。总的来说,进入停止状态的碎片对用户来说是完全不可见的,有可能会被系统回收。

销毁状态
碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进入到销毁状态。或者通过调用FragmentTransaction的remove(),replace()方法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的碎片也会进入到销毁状态

onAttach():当碎片和活动建立关联的时候调用
onCreateView():为碎片创建视图(加载布局)时调用
onActivityCreated():确保与碎片相关联的活动一定已经创建完毕的时候调用
onDestroyView():当于碎片相关联的视图移除时调用
onDetach():当碎片和活动解除关联的时候调用

5、Fragment家族常用的API

Fragment常用的三个类:
android.app.Fragment 主要用于定义Fragment

android.app.FragmentManager 主要用于在Activity中操作Fragment

android.app.FragmentTransaction 保证一些列Fragment操作的原子性,熟悉事务这个词,一定能明白~

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

b、主要的操作都是FragmentTransaction的方法
FragmentTransaction transaction = fm.benginTransatcion();//开启一个事务

transaction.add()
往Activity中添加一个Fragment

transaction.remove()
从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈(回退栈后面会详细说),这个Fragment实例将会被销毁。

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

transaction.hide()
隐藏当前的Fragment,仅仅是设为不可见,并不会销毁

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

6.Fragment与Activity通信方式
1.直接在一个Fragment中调用另外一个Fragment中的方法
我们可以直接在一个Fragment中调用另外一个Fragment的公开方法,前提是要先拿到另外一个Fragment的实例,我们先来看看怎样在左边的Fragment中拿到右边Fragment的实例:

[java] view plain copy print?ContentFragment cf = (ContentFragment) getActivity()                              .getFragmentManager().findFragmentById(                                      R.id.content_fg);                      cf.showPro(name);  

我们通过宿主Activity拿到FragmentManager,进而再拿到右边的Fragment,然后调用右边Fragment里边的showPro方法,其中要传入的参数是左边点击的人名,我们看看右边Fragment中的showPro方法:

[java] view plain copy print?public void showPro(String key) {      list = map.get(key);      adapter = new ArrayAdapter<String>(getActivity(),              android.R.layout.simple_list_item_1, list);      lv.setAdapter(adapter);  }  

先根据传进来的人名拿到该人作品的数据集,然后构造一个adapter赋值给listview,很简单吧。使用这种方式我们可以直接在一个Fragment中调用另一个Fragment的公开方法,从而实现两个Fragment的通信。
这种方法适于那些我们在布局文件中就已经定义了的Fragment,这种Fragment每个都有id,可以通过FragmentManager找到,但是如果我们使用了ViewPager,即每个Fragment都是动态添加进来的,这个时候我们无法通过FragmentManager获得另外一个Fragment的实例,那么该怎么办呢?这时我们就要用到下面这种方式了。
2.使用接口
接口可以实现两个Fragment之间的通信,也可以实现Fragment和Activity之间的通信,这大概是用的比较多的一种方式,也是个人比较推荐的一种方式,使用接口来实现两个Fragment之间通信,要通过宿主Activity中转一下,如果是Fragment和宿主Activity通信则直接调用即可,我们先看看上图中点击韩愈的时候怎么出现他的作品。首先在左边的Fragment中定义一个接口:

[java] view plain copy print?public interface showPro {      public void showProByName(String name);  }  

然后定义一个接口变量:

[java] view plain copy print?private showPro mCallback;  

我们要在宿主Activity中实现这个接口,这样当Fragment调用onAttach方法时我们就可以实例化这个接口了:

[java] view plain copy print?@Override  public void onAttach(Activity activity) {      super.onAttach(activity);      if (activity != null) {          mCallback = (showPro) activity;      }  }  

当mCallback实例化之后,那么我们在点击韩愈的时候就可以调用这里边的showProByName方法了:

[java] view plain copy print?lv.setOnItemClickListener(new OnItemClickListener() {      @Override      public void onItemClick(AdapterView<?> parent, View view,              int position, long id) {          TextView nameTV = (TextView) view;          String name = nameTV.getText().toString();          if ("韩愈".equals(name)) {              mCallback.showProByName(name);          }      }  });  

当然,这个方法的具体实现在宿主Activity中,当宿主Activity实现了showPro接口之后,接着就要实现它里边的方法了:

[java] view plain copy print?public class MainActivity extends Activity implements showPro {      private ContentFragment cf;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          getActionBar().hide();          cf = (ContentFragment) getFragmentManager().findFragmentById(                  R.id.content_fg);      }      @Override      public void showProByName(String name) {          cf.showPro(name);      }  }  

我们在接口的方法中调用右边Fragment中的showPro方法,并将当前人名作为参数传入,这个方法与1中相同,我就不贴代码了。这个方法与1中介绍的方法相比,虽然有点麻烦,但是可以有效的解决在一个Fragment中拿不到另一个Fragment实例的问题,具体应用场景就是ViewPager中的Fragment之间通信。

3.使用广播
不论我们有没有用ViewPager,都可以用广播实现两个Fragment之间的通信,广播算是这里最灵活的通信方式了,我们看看在左边Fragment中发送广播:

[java] view plain copy print?Intent intent = new Intent("showPro");                      intent.putExtra("name", name);                      LocalBroadcastManager.getInstance(getActivity())                              .sendBroadcast(intent);  

在右边Fragment中接收广播:

[java] view plain copy print?LocalBroadcastManager localBroadcastManager = LocalBroadcastManager          .getInstance(getActivity());  IntentFilter intentFilter = new IntentFilter();  intentFilter.addAction("showPro");  BroadcastReceiver br = new BroadcastReceiver() {      @Override      public void onReceive(Context context, Intent intent) {          String key = intent.getStringExtra("name");          list = map.get(key);          adapter = new ArrayAdapter<String>(getActivity(),                  android.R.layout.simple_list_item_1, list);          lv.setAdapter(adapter);      }  };  localBroadcastManager.registerReceiver(br, intentFilter);  

这些都是广播基本的使用方法,我就不啰嗦了。

个人觉得,虽然广播用起来最方便,但是在选择使用哪种通信方式的时候,优先选择上面两种,如果前两种方式都不可以,再考虑使用广播。

4.Fragment直接调用Activity中的public方法
我们也可以直接在Fragment中调用Activity中的公开方法,如下:

[java] view plain copy print?((MainActivity) getActivity()).showProByName(name);  

这里的showProByName就是我们上文贴出来的那个MainActivity中的方法。

原创粉丝点击