Fragment学习(二): 管理Fragment和Fragment通讯
学习 管理 通讯 fragment
2023-09-14 08:56:50 时间
一、 管理Fragment
首先,如果你想在Android3.0及以下版本使用Fragment,你必须引用android-support-v4.jar这个包
然后你写的activity不能再继承自Activity类了,而是要继承android.support.v4.app.FragmentActivity,一些其他的父类也有相应的变化.
此处,我们关系Android3.0以上自带的Fragment的管理,要管理Fragment们,需使用FragmentManager,要获取它,需在Activity中调用方法getFragmentManager()。
你可以用FragmentManager来做以上事情: 1. 使用方法findFragmentById()或findFragmentByTag(),获取activity中已存在的fragment们。 2. 使用方法popBackStack()从activity的后退栈中弹出fragment们(这可以模拟后退键引发的动作)。 3. 用方法addOnBackStackChangedListerner()注册一个侦听器以监视后退栈的变化。 你还可以使用FragmentManager打开一个FragmentTransaction来执行fragment的事务,比如添加或删除Fragment执行Fragment的事务 在Activity中使用Fragment的一个伟大的好处是能跟据用户的输入对Fragment进行添加、删除、替换以及执行其它动作的能力。你提交的一组Fragment的变化叫做一个事务。事务通过FragmentTransaction来执行。你还可以把每个事务保存在Activity的后退栈中,这样就可以让用户在fragment变化之间导航(跟在activity之间导航一样)。 你可以通过FragmentManager来取得FragmentTransaction的实例,如下:
FragmentManager fragmentManager = getFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();一个事务是在同一时刻执行的一组动作(很像数据库中的事务)。你可以用add(),remove(),replace()等方法构成事务,最后使用commit()方法提交事务。 在调用commint()之前,你可以用addToBackStack()把事务添加到一个后退栈中,这个后退栈属于所在的Activity。有了它,就可以在用户按下返回键时,返回到Fragment们执行事务之前的状态。 如下例:演示了如何用一个Fragment代替另一个Fragment,同时在后退栈中保存被代替的Fragment的状态。
//Create new fragment and transaction Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction=getFragmentManager().beginTransaction(); //Replace whatever is in the fragment_container view with thisfragment, //and add the transaction to the backstack transaction.replace(R.id.fragment_container,newFragment); transaction.addToBackStack(null); //Commit the transaction transaction.commit();解释:newFragment代替了控件ID为R.id.fragment_container所指向的ViewGroup中所含的任何Fragment。然后调用addToBackStack(),此时被代替的Fragment就被放入后退栈中,于是当用户按下返回键时,事务发生回溯,原先的Fragment又回来了。 如果你向事务添加了多个动作,比如多次调用了add(),remove()等之后又调用了addToBackStack()方法,那么所有的在commit()之前调用的方法都被作为一个事务。当用户按返回键时,所有的动作都被反向执行(事务回溯)。 事务中动作的执行顺序可随意,但要注意以下两点: 1. 你必须最后调用commit()。 2. 如果你添加了多个Fragment,那么它们的显示顺序跟添加顺序一至(后显示的覆盖前面的)。 如果你在执行的事务中有删除Fragment的动作,而且没有调用addToBackStack(),那么当事务提交时,那些被删除的Fragment就被销毁了。反之,那些Fragment就不会被销毁,而是处于停止状态。当用户返回时,它们会被恢复。 密技:对于fragment事务,你可以应用动画。在commit()之前调用setTransition()就行。 但是,调用commit()后,事务并不会马上执行。它会在activity的UI线程(其实就是主线程)中等待直到线程能执行的时候才执行(废话)。如果必要,你可以在UI线程中调用executePendingTransactions()方法来立即执行事务。但一般不需这样做,除非有其它线程在等待事务的执行。 警告:你只能在activity处于可保存状态的状态时,比如running中,onPause()方法和onStop()方法中提交事务,否则会引发异常。这是因为fragment的状态会丢失。如果要在可能丢失状态的情况下提交事务,请使用commitAllowingStateLoss()。
二、 Fragment与Activity通讯
与Activity通讯
尽管Fragment的实现是独立于Activity的,可以被用于多个Activity,但是每个Activity所包含的是同一个Fragment的不同的实例。 Fragment可以调用getActivity()方法很容易的得到它所在的activity的对象,然后就可以查找activity中的控件们(findViewById())。例如: View listView =getActivity().findViewById(R.id.list);同样的,Activity也可以通过FragmentManager的方法查找它所包含的Frament们。例如:ExampleFragment fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment);
Activity响应Fragment的事件 有时,你可能需要Fragment与Activity共享事件。一个好办法是在Fragment中定义一个回调接口,然后在Activity中实现之。 例如,还是那个新闻程序的例子,它有一个Activity,Activity中含有两个Fragment。FragmentA显示新闻标题,FragmentB显示标题对应的内容。FragmentA必须在用户选择了某个标题时告诉Activity,然后Activity再告诉FragmentB,FragmentB就显示出对应的内容(为什么这么麻烦?直接FragmentA告诉FragmentB不就行了?也可以啊,但是你的Fragment就减少了可重用的能力。现在我只需把我的事件告诉宿主,由宿主决定如何处置,这样是不是重用性更好呢?)。如下例,OnArticleSelectedListener接口在FragmentA中定义:
public static class FragmentA extends ListFragment{ //Container Activity must implement this interface public interface OnArticleSelectedListener{ public void onArticleSelected(Uri articleUri); ...
然后Activity实现接口OnArticleSelectedListener,在方法onArticleSelected()中通知FragmentB。当Fragment添加到Activity中时,会调用Fragment的方法onAttach(),这个方法中适合检查Activity是否实现了OnArticleSelectedListener接口,检查方法就是对传入的activity的实例进行类型转换,如下所示:
public static class FragmentA extends ListFragment{ OnArticleSelectedListener mListener; ... @Override public void onAttach(Activity activity){ super.onAttach(activity); try{ mListener =(OnArticleSelectedListener)activity; }catch(ClassCastException e){ throw new ClassCastException(activity.toString()+"must implement OnArticleSelectedListener"); ...
如果Activity没有实现那个接口,Fragment抛出ClassCastException异常。如果成功了,mListener成员变量保存OnArticleSelectedListener的实例。于是FragmentA就可以调用mListener的方法来与Activity共享事件。例如,如果FragmentA是一个ListFragment,每次选中列表的一项时,就会调用FragmentA的onListItemClick()方法,在这个方法中调用onArticleSelected()来与activity共享事件,如下:
public static class FragmentA extends ListFragment{ OnArticleSelectedListener mListener; ... @Override public void onListItemClick(ListView l,View v,int position,long id){ //Append the clicked items row ID with the content provider Uri Uri noteUri =ContentUris.withAppendedId(ArticleColumns.CONTENT_URI,id); //Send the event and Uri to the host activity mListener.onArticleSelected(noteUri); ...onListItemClick()传入的参数id是列表的被选中的行ID,另一个Fragment用这个ID来从程序的ContentProvider中取得标题的内容。
最近一段时间忙于找工作,找到工作之后忙于项目上线,好久没有写过博客,现在感觉终于闲暇了,写一写这次项目中需要总结提炼的知识点,给自己留个印象吧,毕竟好记性不如烂笔头。
Activity和Fragment之间解耦 看鸿洋博客:http://blog.csdn.net/lmj623565791/article/details/42628537,整理下一些关键点 public class ContentFragment extends Fragment private String mArgume...
相关文章
- Esp8266学习之旅① 搭建开发环境,开始一个“hellow world”串口打印。
- 一起学习Vuex 4.0的状态管理(Vite)
- C语言学习
- C语言中的输入和输出函数【C语言学习笔记】
- Rust学习笔记Day18 智能指针Cow/MutexGuard
- 深度学习的学习路线
- RabbitMQ学习之(二)_Centos6下安装RabbitMQ及管理配置详解程序员
- Java基础学习笔记十六 集合框架(二)详解编程语言
- 教程MySQL入门视频教程:学习玩转数据库管理(mysql视频)
- Linux服务器管理之旅:学习使用Shell命令(linux服务器管理命令)
- 深入学习:如何使用XAMPP管理MySQL(xampp使用mysql)
- 学习MySQL集群的节点部署和管理(mysql节点)
- 控制从零开始:学习Linux版本控制(初学linux版本)
- 深入解读Oracle参考手册,轻松学习数据库管理技巧(oracle参考手册)
- MySQL字段信息表:学习如何管理(mysql字段信息表)
- 学习Oracle:如何管理用户名?(oracle管理用户名)
- 学习Linux:掌握运用top命令一次搞定进程管理(linuxtop一次)
- Oracle技术培训班,让你轻松学习数据库开发知识(oracle技术培训班)
- DB2UDBV8.1管理学习笔记(二)
- DB2UDBV8.1管理学习笔记(一)
- Ruby中的方法(函数)学习总结
- C#中的lock、Monitor、Mutex学习笔记