🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# **Fragment** * * * * * 1. Fragment是什么 2. Fragment能实现哪些效果?为什么我要使用Fragment 3. Fragment的具体使用细节? 4. 如何向别人讲解,熟练使用Fragment? ## **一.Fragment是什么?** Fragment是Android系统提供的“组件”[1],以提供“灵活构建UI布局”能力。 > 注:什么是组件?组件,是由系统/依赖库等其他外部因素创建的“Java类”,它们存在的形式,通常是Java类;不同组件唯一的不同之处是——不同的组件,提供各不相同的“能力”。 > ## **二.Fragment经常出现在哪些经典的UI布局当中?** * 左右布局,如新闻模块、侧边栏导航模块、外卖点餐系统 * 点击列表查看详情布局,如新闻列表-查看新闻详情 * 常见tab切换页 * 此次研究对象,漫画APP中,使用到Fragment的模块和页面: 1. 主页 2. 点击侧边栏显示详情内容 ## **三.如何开始使用Fragment?** 为了保证资料来源的权威性,本人将直接引用Google官方提供的Android开发资料 在使用Fragment之前,再次明确我作此小节的目的: 学会创建、实现、定义、引用Fragment。——是本小节的核心、也是我作此文的目的 注意,在确保诸位能学会Fragment之前,一定要牢记这里包含了四步曲: 前两步定义、创建、实现只是作好了”食材“; 第三、四步正确定义、引用Fragment,才能真正的发挥Fragment功力,进而用Fragment作出”美味可口的大餐“。 我都有点迫不及待了,快来和我一起了解Fragment使用方法吧! ### **创建和实现Fragment** 创建Fragment的方式一共有两步:代码创建Java类和XML创建视图布局。 创建Java文件的步骤如下: 在你的src/main/java 目录下,创建一个名为ArticleFragment的文件,粘贴复制下面的代码 ~~~ import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.ViewGroup; public class ArticleFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment return inflater.inflate(R.layout.article_view, container, false); } } ~~~ 瞧,动态创建的方式如此简单,就跟我们初学Java时,创建一个Person类那样简单,不同的是,我们需要通过import导入Android的开发包;当然,按住ctrl+shift+o,即可快速导入Fragment关联的包;还有关键的一点,在实际开发中,上述代码将会被重复写无数多次,你有的是机会去记住这段代码。而此刻,我们学习的重点是——哪一段代码,可以创建Fragment,因此,作为新手,我建议直接粘贴复制此段代码。以便于进行下一步练习。 我们再来看看创建Fragment视图布局的方式,也就是说,我们即将实现Fragment的能力——UI布局: 在你的res/layout/目录下创建news_articles.xml文件,直接粘贴复制下面的布局语法 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <!-- TODO: Update blank fragment layout --> <TextView android:layout_width="match_parent" android:layout_height="match_parent" android:text="@string/hello_blank_fragment" /> </FrameLayout> 瞧,依然是如此的简单!我们在xml文件中,加入了TextView文本组件,这即将是Fragment要显示的内容 我们通过在Java目录下创建Java文件,在laout目录下创建xml文件的形式,完成了第一步:Fragment的创建。可是,完成创建和实现,并不意味着就万事大吉了,我们还需要实现它、正确定义、引用它,才能在手机屏幕上看到Fragment这个可爱的家伙! ### **定义Fragment** 老实说,定义Fragment并不简单,动态定义和静态定义 动态定义,在Java文件中通过new ArticleFragment()的方式,直接完成对Fragment的定义,这样引用,也是动态引用的 静态定义,是在诸如res/laout/activity_home.xml中(知识举例),创建Fragment,通过引用activity.xml中的fragment,完成静态定义、这样定义,引用方式也称之为静态引用 先说静态引用,这是我们上一步创建的 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <fragment android:name="com.example.android.fragments.ArticleFragment" android:id="@+id/article_fragment" android:layout_weight="2" android:layout_width="0dp" android:layout_height="match_parent" /> </LinearLayout> 引用Fragment 下列这段代码,讲解了在activity中静态引用fragment,这样activity讲直接显示news_articles.xml里的布局,连fragment得实例化对象都还没看到! ~~~ import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.news_articles); } } ~~~ 这种静态引用的核心,就是通过系统已经定义好的函数——setContentView()直接加载指定的xml布局文件 记住,setCOntentView()函数,这个函数相当关键。 接着讲动态引用,动态引用Fragment,正是本文核心中的核心。实际开发,也是用的最多的! 先在res/layout/目录下创建news_article.xml文件,语法如下 ~~~ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fragment_container" android:layout_width="match_parent" android:layout_height="match_parent" /> ~~~ 上述语法只是创建了一个framelayout布局(不是fragment布局),没有任何内容 (在看下面这段代码之前,先使用第一步创建ArticleFragment的方式,再创建一个类似的名为HeadlineFragment的Fragment) ~~~ import android.os.Bundle; import android.support.v4.app.FragmentActivity; public class MainActivity extends FragmentActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.news_articles); // Check that the activity is using the layout version with // the fragment_container FrameLayout if (findViewById(R.id.fragment_container) != null) { // However, if we're being restored from a previous state, // then we don't need to do anything and should return or else // we could end up with overlapping fragments. if (savedInstanceState != null) { return; } // Create a new Fragment to be placed in the activity layout HeadlinesFragment firstFragment = new HeadlinesFragment(); // In case this activity was started with special instructions from an // Intent, pass the Intent's extras to the fragment as arguments firstFragment.setArguments(getIntent().getExtras()); // Add the fragment to the 'fragment_container' FrameLayout getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, firstFragment).commit(); } } } ~~~ 上述代码有三处关键的地方 1. setContentView(R.layout.news_articles); 2. HeadlinesFragment firstFragment = new HeadlinesFragment(); 3. getSupportFragmentManager().beginTransaction() .add(R.id.fragment_container, firstFragment).commit(); 解释和说明: 1. 先为Activity加载布局,Activity此刻只有一个framelayout空布局 2. 再动态创建一个Fragment子类对象——HeadlinesFragment 3. 最最关键的,第三段超长的代码链,一句话、一个标点符号都不能错。 **最为关键**的是.add(R.id.fragment_container, firstFragment) R.id.fragment_container指的是activity首先加载的framelayout空布局id, 而firstFragment指的是fragment对象,通过add()函数,firstFragment讲被添加到activity中,从而显示到屏幕上! 当然,千万别忘了commit()!只有确保commit,才能保证系统正确的执行你前面写的一大段代码! ## **四.Fragment的使用细节** 老实说,Fragment的使用细节,没什么值得讲的地方,新手如果确保前三小节看懂、会用,避免语法错误、步骤错误,使用Fragment就不可能出现BUG。 但有几点,值得我分享给诸位,坐下来好好谈谈的技术点: 1. 先再次复述一遍Fragment的创建、实现、定义、引用的步骤,尤其是动态引用小节中的第三步,那段超长的代码链,是否倒背如流? 2. Acitivity、Fragment、FragmentManager、FragmentTransaction, 2.1Activity与Fragment的关系——生命周期是如何影响Activity和Fragment的 2.1FragmentTransaction的API,除了add(),试试其他方法replace()、hide()、remove()等 细节部分,互联网上有太多的Android同仁介绍过了,写多了,对于本人,不能给予Android领域更多贡献,在这里便不多费口舌,献出我认为较好的关于“Fragment使用细节”的链接,有兴趣的可以深究。 1.Android API网站——FragmentTransaction索引 https://developer.android.google.cn/reference/android/app/FragmentTransaction.html 2.Android Fragment培训课程 https://developer.android.google.cn/training/basics/fragments/index.html 2.Android Fragment 真正的完全解析(下) http://blog.csdn.net/lmj623565791/article/details/37970961/ ## **五.学会向别人讲解Fragment** 当你有向别人讲解Fragment的需要时,你一定身处下面两种角色之一:毕业答辩、求职招聘。 * 参与毕业答辩的同学,担心被老师问到Fragment,手慌脚乱,不知从何说起 * 即将参加求职招聘的同仁,不善言辞的程序员,紧张起来,也容易乱说一通。 此节的目的,正在于此。 #### 1.Fragment是什么 答:谷歌提供的碎片化组件,可以附着在Activity上,组成多个碎片布局。 #### 2.Fragment如何用, 3.FragmentManager 、FragmentTransition是Fragment的管理器和发布器,管理器既可以将Fragment绑定至Activity上,也可以创建发布器对象。一旦创建好了发布器对象,发布器FragmentTransition便可通过commit()函数,通知Actiivty,将Fragment添加到屏幕之上。 #### 3.Fragment如何管理? 这里的管理,往小了说,是通过管理器FragmentManager管理的,FragmentManager有强大、全面的管理Fragment的函数,对Fragment的操作,包括索引、查找、增加、删除、压栈、出栈、回退等功能。时间以及瞬时记忆力等原因,不在这里一一说明了。 但有一点,是面试、答辩值得一说的,就是Fragment管理器,能实现哪些常见的需求? 比如查找,可以找到已经创建且并未销毁的Fragment,这样可以复用对象,减少内存消耗; 比如增加,可以继续创建一个Fragment,附着在Activity上,旧的Fragment,只是看不见、或者暂时存放至后台了 比回退,可以实现浏览器打开一系列页面,按住Back键位,还能从当前页面,返回到上一历史页面去,这在实际开发,是相当有用的。 但具体的API,面试、答辩,并不一定需要说出来,最重要的是,讲出来,Fragment以及Fragment的管理器、发布器,可以实现哪些功能和需求,实际开发,是允许我们去查询资料和文档的!