Android学习笔记十三.深入理解fragment(一) - 新闻资讯 - 云南小程序开发|云南软件开发|云南网站建设-昆明葵宇信息科技有限公司

159-8711-8523

云南网建设/小程序开发/软件开发

知识

不管是网站,软件还是小程序,都要直接或间接能为您产生价值,我们在追求其视觉表现的同时,更侧重于功能的便捷,营销的便利,运营的高效,让网站成为营销工具,让软件能切实提升企业内部管理水平和效率。优秀的程序为后期升级提供便捷的支持!

您当前位置>首页 » 新闻资讯 » 技术分享 >

Android学习笔记十三.深入理解fragment(一)

发表时间:2020-10-19

发布人:葵宇科技

浏览次数:42


深刻懂得fragment(一)
    Fragment是Android3.0惹人的新API,可以把Fragment想成Activity中的模块,这个模块有本身的构造,有本身的生命周期,零丁处理本身的输入,在Activity运行的时刻可以加载或者移除Fragment模块。 可以把Fragment设计成可以在多个Activity中复竽暌姑的模块,当开辟的应用法度榜样同时实用于平板电脑和手机时,可以应用Fragment实现灵活的构造,改良用户体验。
[img]http://img.blog.csdn.net/20150104174430573?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
一、Fragment的特点
1.Fragment老是作为Activity界面的构成部分。Fragment可调用getActvity()办法获取它地点的Activity,Activity可调用FragmentManager的findFragmentById()或findFragmentByTag()办法来获取Fragment。个中,fragment的id或tag在其构造文件<fragment../>元素中定义。
2.在Activity运行过程中,可调用FragmentManager的add()、remove()、WordStr()、办法动态地添加、删除或调换Fragment。
3.一个Activity可以同时组合多个Fragment;反过来,一个Fragment也可能被多个Activity复竽暌姑;
4.Fragment可以响应本身的输入事宜、并拥有本身的声明周期,但它们的生命周期直接被其他所属的Activity的生命周期控制。
二、Fragment的生命周期
    因为Fragment必须嵌入在Acitivity中应用,所以Fragment的生命周期和它地点的Activity是密切相干的。如不雅Activity是暂停状况,个中所有的Fragment都是暂停状况;如不雅Activity是stopped状况,这个Activity中所有的Fragment都不克不及被启动;如不雅Activity被烧毁,那么它个中的所有Fragment都邑被烧毁。然则,当Activity在晃荡状况,可以自力控制Fragment的状况,比如加上或者移除Fragment。当如许进行fragment transaction(转换)的时刻,可以把fragment放入Activity的back stack中,如许用户就可以进行返回操作。
1.Fragment的几个状况
(1)晃荡状况:当前Fragment位于前台,用户可见、可以获得核心;
(2)暂停状况:其他Acitvity位于前台,该Fragment依然可见,只是不克不及获得核心;
(3)停止状况:该Fragment弗成见,掉去核心
(4)烧毁状况:该fragment被完全删除,或者Fragment地点的Activity被停止
2.与Fragment有关的办法
    如最常见的就是onCreateView()办法,其感化是返回一个View对象将Fragment显示出来。
[img]http://img.blog.csdn.net/20150104174459933?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center
三、Fragment所需的库
    应用Fragment时,须要持续Fragment或者Fragment的子类(DialogFragment, ListFragment, PreferenceFragment, WebViewFragment),所以Fragment的代码看起来和Activity的类似。因为Fragment是Android 3.0及以上体系特有的API,如不雅我们须要开辟低版本的应用软件,则须要惹人Fragment所支撑的库。
    Support Library是一个供给了API库函数的JAR文件,如许就可以在旧版本的Android上应用一些新版本的APIs.比如android-support-v4.jar.它的完全路径是:
                <sdk>/extras/android/support/v4/android-support-v4.jar. 它就供给了Fragment的APIs,使得在Android 1.6 (API level 4)以上的体系都可以应用Fragment。应用该支撑库须要分两步:
1.添加支撑库到工程项目中
    将上述的包拷入libs项面前目今的libs文件夹,然后在项目标Properties中添加:右键单击项目,选Properties,左边选Java Build Path,然后Add External JARs…,添加android-support-v4.jar.
[img]http://img.blog.csdn.net/20150104174517966?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

[img]http://blog.csdn.net/u012637501/article/details/42395259/file:/C:/Users/Jiangdongguo/AppData/Local/YNote/data/jiangdongguo2013@126.com/5ba3b6b05aed44bca7a3526513263b4b/clipboard.png
2.导入Fragment、FragmentManager到工程中
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
留意,当创建包含Fragment的Activity时,如不雅用的是Support Library,那么持续的就应当是FragmentActivity而不是Activity.
四、Fragment核心分析
1.创建Fragement,并设置该Fragment的显示界面
    与创建Activity类似,开辟者实现的Fragment必须持续Fragment基类,Android供给了4种Fragment:(1)DialogFragment-对话框界面的Fragment;(2)ListFragment-实现列表界面的Fragment;(3)PreferenceFragment-选项设置界面的Fragment;(4)WebViewFragment-WebView界面的Fragment。创建Fragment平日须要实现三个回调办法:
(1)onCreate()
    体系在创建Fragment的时刻调用这个办法,这里应当初始化相干的组件,一些即就是被暂停或者被停止时依然须要保存的器械。 
(2)onCreateView() 
   当第一次绘制Fragment的UI时体系调用这个办法,必须返回一个View。组件View对应的构造文件,即为该Fragment将会显示的界面。如不雅Fragment不供给UI也可以返回null。 
留意,如不雅持续自ListFragment,onCreateView()默认的实现会返回一个ListView,所以不消本身实现。 
(3)onPause() 
   当用户分开Fragment时第一个调用这个办法,须要提交一些变更,因为用户很可能不再返回来。
示例1:实现一个Fragment的构造界面。经由过程onCreateView()办法,将example_fragment构造资本文件设置为该Fragment的显示界面。
源码:
public static class ExampleFragment extends Fragment
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
  Bundle savedInstanceState)
    {
        // Inflate the layout for this fragment
         return inflater.inflate(R.layout.example_fragment,     //指清楚明了当前的Fragment对应的资本文件
                            container,                 //父容器控件
                             false);                     //*注解是否链接该构造和其父容器。这里设置为false,是因为体系已经插入了                 
                                                             这个构造到父控件,设置为true将会产生多余的一个View Group*/ 
     }
}
注释:onCreateView办法中container参数代表该Fragment在Acitivity的父控件;savedInstanceState供给了上一个实例的数据。


2.把一个Fragment参加到Activity中
    Fragment不克不及零丁存在,必须依附在Activity上。当Fragment被参加到指定的Activity中时,它会处在对应的View Group中。平日,Fragment加载到一个Activity有两种方法:一种是在layout中应用标签<fragment>声明;另一种办法是在代码中把Fragment参加到一个Activity的指定ViewGroup中。
(1)经由过程被加载Activity的构造文件将Fragment加载到指定Acitivity
    我们只需在指定Activity的构造文件中,添加一个<fragment.../>元素将Fragment作为一个子标签参加即可。

示例2:实现加载一个列表Fragment到指定的Activity中显示
源码:
<?xml version="1.0" encoding="utf-8"?> 
<!-- 定义一个水等分列的LinearLayout,并指定应用中等分隔条 --> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent"	
android:layout_height="match_parent" 
android:orientation="horizontal" 
android:layout_marginLeft="16dp" 
android:layout_marginRight="16dp" 
android:divider="?android:attr/dividerHorizontal" 
android:showDividers="middle"> 
<!-- 应用资本文件方法:添加一个fragment到Activity中 --> 
    <fragment 
            android:name="com.example.android_fragment_1.BookListFragment" 
            android:id="@+id/book_list" 
            android:layout_height="match_parent" 
            android:layout_width="0dp" 
            android:layout_weight="1"/> 
</LinearLayout>

注释:android:name属性为该须要加载的Fragment完全类名(包.类名);android:id属性为该Fragment的独一标识符ID,我们可以经由过程ID实现对该Fragment进行添加、删除等操作。


(2)应用FragmentManager和FragmentTransaction将一个Fragment加载到指定Activity的ViewGroup中

    当Activity处于Running状况下的时刻,可以应用这种办法在Activity的构造中动态地参加Fragment,只须要指定参加这个Fragment的父View Group即可。
    FragmentManager重要完成获取指定Fragment,将Fragment大年夜后台弹出栈、为后台Fragment注册一个监听器。
    FragmentTransaction则完成Fragment的添加、删除、调换等事务,每个FragmentTransaction可以包含多个对Fragment修改,比如包含调用了多了add()、remove()和WordStr()操作,最后还调用commit()办法提交事务即可。
    起首、经由过程FragmentManager对象获得一个FragmentTransaction对象,借助FragmentTransaction对象实现Acitivity对Fragment履行添加、删除、调换等操作。
    FragmentManager fragmentManager=getFragmentManager();    //如用的是支撑包,则为getSupportFragmentManager()
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();//打开事务
   其次,将实现的名为BookListFragment的Fragment添加到View Group中
    BookListFragment booklistfragment = new BookListFragment();        //创建一个图书列表Fragment

    fragmentTransaction.add(R.id.fragment_container, booklistfragment );  //添加图书列表Fragment到标识为fragment_container容器

    fragmentTransaction.commit();                                                             //提交事务改变生效-使View容器显示图书列表Fragment
注释1:如不雅想使应用法度榜样许可用户按BACK返回键回到调换Fragment之前的状况(即上一个Fragment),我们可以将事务添加到back栈。
       fragmentTransaction.addtoBackStack(null);
注释2:除了上述添加一个Fragment到Activity的View父容器中,还可声调换或者删除容器中已有的Fragment.调用commit()办法使得FragmentTransaction实例的改变生效。
        fragmentTransaction.WordStr(R.id.fragment_container, booklistfragment);    //调换容器类已有的Fragment
注释3:R.id.fragment_container为当前Activity构造中ID为fragment_container的容器,在Activity界面构造文件中定义。
res/layout/main.xml
[img]http://blog.csdn.net/u012637501/article/details/42395259/file:/C:/Users/Jiangdongguo/AppData/Local/YNote/data/jiangdongguo2013@126.com/f8ad36bb3b734bb4b7ce10deb1d2afb0/clipboard.png[img]http://img.blog.csdn.net/20150104174604406?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center


3.Fragment与Activity通信
    经由过程第二步将一个Fragment加载到指定的Activity之后,该Fragment必须与Activity交互信息,这就须要Fragment能获取它地点的Activity,Activity也能获取它所包含的随便率性的Fragment。
1)获取目标对象
(1)Fragment获取它地点的Activity:
    调用Fragment的getActivity()办法即可返回它地点的Activity。
(2)Activity获取它所包含的Fragment:
    调用Activity接洽关系的FragmentManager的findFragmentById(int id)或findFragmentByTag(String tag)办法即可获取指定的Fragment。
        ExampleFragment fragment =(ExampleFragment)getFragmentManager().findFragmentById(R.id.example_fragment)
    注释:我们可以在Activity界面元件中应用<fragment.../>添加Fragment时,可认为<fragment../>元素添加android:name或android:tag属性来标识Fragment,接下来Activity将可以经由过程findFragmentById(int id)等办法来获取Fragment。


2)Frament与Activity之间的数据传递
(1)Activity向Fragment传递数据:
    在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)办法即可将Bundle数据包传给Fragment;
(2)Fragment向Activity传递数据或Activity需在Fragment运行中进行及时通信:
    在Fragment中定义一个内部回调接口,再让包含该Fragment的Activity实现该回调接口,如许Fragment即可调用该回调办法将数据传给Activity。


3)activity响应fragment的事宜完全解析
     有时,你可能须要fragment与activity共享事宜。一个好办法是在fragment中定义一个回调接口,然后在activity中实现这个回调接口。
    例如,照样那个消息法度榜样的例子,它有一个activity,activity中含有两个fragment。fragmentA显示消息标题,fragmentB显示标题对应的内容。fragmentA必须在用户选择了某个标题时告诉activity,然后activity再告诉fragmentB,fragmentB就显示出对应的内容(为什么这么麻烦?直接fragmentA告诉fragmentB不就行了?也可以啊,然则你的fragment就削减了可重用的才能。如今我只需把我的事宜告诉宿主,由宿主决定若何处理,如许是不是重用性更好呢?)。如下例,
(1)在fragmentA(BookListFragment)中定义OnBookSelectedListener回调接口:

public class BookListFragment extends ListFragment
 {
           private OnBookSelectedListener whichbook; //接口对象

 public interface OnBookSelectedListener

         {
             public void onBookSelected(Integer id); //参数为Map集合的键
         }
        .....
}


(2)  然后在activity实现接口OnBookSelectedListener,在办法onBookSelected()中通知fragmentB(BookDetailFragment ),即Activity大年夜FragmentA获取传入的ID,用来启动FragmentB。
如下所示:  
public class SelectBookActivity extends Activity implements BookListFragment.OnBookSelectedListener
{
    ......
     public void onItemSelected(Integer id)
     {
          //a.创建Bundle,预备向Fragment传入参数
          Bundle bundle=new Bundle();
           bundle.putInt(BookDetailFragment.ITEM_ID, id); //装入值id到"item_id"键
          //b.创建BookDetailFragment对象,并项Fragment传入参数
          BookDetailFragment fragment=new BookDetailFragment();
          fragment.setArguments( bundle);
          //c.应用fragment调换book_detail_container容器当前显示的Fragment
          getFragmentManager().beginTransaction()
                                            .WordStr(R.id.book_detail_container, fragment)
                                            .commit();
          /*注释:这一句等价于....
           * FragmentManager Manager=getFragmentManager();
           * FragmentTransaction Transaction=Manager.beginTransaction();
           * Transaction.WordStr(R.id.book_detail_container, Manager);
           * Transaction.commit();
           * */
     }

}                                                                                                                          


(3)实现fragmentA(BookListFragment)的onAttach()办法,将fragmentA添加并显示到Activity中

    当fragmentA添加到activity中时,会调用fragmentA的办法onAttach(),这个办法中合适检查activity是否实现了OnBookSelectedListener接口,检查办法就是对传入的activity的实例进行类型转换,如不雅activity没有实现那个接口,fragment抛出ClassCastException异常。如不雅成功了,mListener成员变量保存OnArticleSelectedListener的实例。于是fragmentA就可声调用mListener的办法来竽暌闺activity共享事宜。
public void onAttach(Activity activity)
 {
      super.onAttach(activity);
      //a.如不雅Activity中没有实现Callbacks接口,抛出异常
      if(!(activity instanceof Callbacks))
      {
           throw new IllegalStateException("异常:BookListFragment地点的Activity必须实现Callback接口!");
      }
      //把该Activity当成whichbook对象(缺乏这一句话,导致出现NullPointerException缺点)
       whichbook=( BookListFragment)activity;
 }


(4)在fragmentA中实现onListItemClick()响应activity发出的事宜(Fragment向Activity传递ID)
      如不雅fragmentA是一个ListFragment,每次选中列表的一项时,就会调用fragmentA的onListItemClick()办法,在这个办法中调用onBookSelected()来竽暌闺activity共享事宜。onBookSelected()传入的参数id是列表的被选中的行ID,另一个fragment(B)( BookDetailFragment )用这个ID来大年夜法度榜样的ContentProvider中取得标题标内容。

@当用户单击某列表项时激发该回调办法
 public void onListItemClick(ListView l, View v, int position, long id) {
      super.onListItemClick(l, v, position, id);
       OnBookSelectedListener.onBookSelected(BookContent.ITEMS.get(position).id);//激发 OnBookSelectedListener接口的onBookSelected办法
 }
[img]http://img.blog.csdn.net/20150104174608448?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMjYzNzUwMQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

[img]http://blog.csdn.net/u012637501/article/details/42395259/file:/C:/Users/Jiangdongguo/AppData/Local/YNote/data/jiangdongguo2013@126.com/e1c3b917a5384da58fb94accc55657d0/clipboard.png

参考:
http://www.cnblogs.com/mengdd/archive/2013/01/08/2851368.html
http://blog.csdn.net/t12x3456/article/details/8119607

相关案例查看更多