博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android学习之Fragment解析
阅读量:4607 次
发布时间:2019-06-09

本文共 6431 字,大约阅读时间需要 21 分钟。

1.定义
    Fragment中文解释是碎片的意思,主要用在大屏幕设备上,例如平板电脑上,支持更加动态和灵活的UI设计。
Fragment在你的应用中相当于是一个模块化和可重用的组件,因为Fragment定义了它自己的布局,以及通过使用它自己的生命周期回调方法定义了它自己的行为,你可以将Fragment包含到多个Activity中。
2.特点
(1)Fragment可以作为Activity界面的一部分组成出现;
(2)可以在一个Activity中同时出现多个Fragment,并且一个Fragment也可以在多个Activity中使用;
(3)在Activity运行过程中,可以添加、移除或者替换Fragment;
(4)Fragment可以响应自己的输入事件,并且有自己的生命周期,它们的生命周期会受宿主Activity的生命周期影响。
3.生命周期
Fragment必须是依存于Activity而存在的,因此Activity的生命周期会直接影响到Fragment的生命周期。
生命周期中涉及的方法如上图所示,具体触发条件如下所述。
  • onAttach()
    • 当Fragment被添加到Activity时候会回调这个方法,并且只调用一次;
  • onCreate()
    • 创建Fragment时会回调,只会调用一次;
  • onActivityCreated()
    • 当Fragment所在的Activity启动完成后调用;
  • onCreateView()
    • 每次创建都会去绘制Fragment的View组件时回调该方法;
  • onStart()
    • 启动Fragment
  • onResume()
    • 恢复Fragment时会被回调,调用onStart()方法后面一定会调用onResume()方法;
  • onStop()
    • 停止Fragment
  • onDestroyView()
    • 销毁Fragment所包含的View组件时调用
  • onDestroy()
    • 销毁Fragment时被回调
  • onDetach()
    • Fragment从Activity中删除时会回调该方法,并且这个方法只会调用一次

4.静态加载

     这是使用Fragment最简单的一种方式,把Fragment当成普通的控件,直接写在Activity的布局文件中,用布局文件调用Fragment。

    (1)新建Fragment,重写onCreateView决定Fragment布局

@Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        return inflater.inflate(R.layout.fragment_static, container, false);    }
   (2)在宿主Activity中手动添加Fragment,就把它当做普通的控件一样,在xml文件中使用。name属性填写fragment的包路径,Activity通过findFragmentById()或者findFragmentByTag()获取Fragment。

    这样在宿主Activity中就能看到Fragment了。

5.动态加载

     上面的静态加载是最基本的方法,下面解析下动态加载的原理。

    (1)原理

  动态加载,顾名思义是通过代码的方式在Activity中加载Fragment。

  通过撰写代码将Fragment添加到一个Activity layout中,这里需要采用Fragment的事务处理(FragmentTransaction),有点类似数据库的事务处理。

  1. 根据用户的交互情况,对Fragment进行添加、移除、替换,以及执行其他动作,提交给Activity的每一套变化被称作一个事务;
  2. 每一个事务都是同时执行一套变化,可以再一个事务中设置你所有想执行的变化,包括add(),remove(),replace(),然后提交给Activity,最后调用commit()方法;
  3. 如果允许用户通过按下BACK按键返回到前一个Fragment状态,调用commit()之前可以加入addToBackStack()方法。

 (2)具体实现

  通过新建两个Fragment,并在这两个Fragment的Layout中添加了ImageView,用来放置图片,而在宿主Activity中将这两个Fragment动态切换,实现图片的自由切换。代码结构如下图所示。

 

 

新建Fragment(Image1Fragment,Image2Fragment),并添加了两个layout文件(fragment_image1,fragment_image2),其中部分代码如下:

Image1Fragmet代码:

@Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // 获取Fragment的View        View view=inflater.inflate(R.layout.fragment_image1,container,false);         return view;    }

fragment_image1.xml文件代码如下:

宿主MainActivity的代码如下,通过FragmentManager得到FragmentTransaction,然后通过replace()方法实现两个Fragment之间的切换,最后实现了Commit()方法:

protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //获取两个按钮的View        bt1=(Button)findViewById(R.id.bt1);        bt2=(Button)findViewById(R.id.bt2);        bt1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //主Activity动态加载Fragment                FragmentManager fragmentManager=getFragmentManager();                //处理Fragment事务                FragmentTransaction beginTransaction=fragmentManager.beginTransaction();                //获取Image1Fragment实例                Image1Fragment image1Fragment=Image1Fragment.newInstance("Activity传递图片1到Fragment中");                //替换操作                beginTransaction.replace(R.id.imageLayout,image1Fragment);                //允许用户通过按下BACK按键返回到前一个Fragment状态                beginTransaction.addToBackStack(null);                beginTransaction.commit();            }        });        bt2.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //主Activity动态加载Fragment                FragmentManager fragmentManager=getFragmentManager();                //处理Fragment事务                FragmentTransaction beginTransaction=fragmentManager.beginTransaction();                //获取Image1Fragment实例                Image2Fragment image2Fragment=Image2Fragment.newInstance("Activity传递图片2到Fragment中");                //替换操作                beginTransaction.replace(R.id.imageLayout,image2Fragment);                //允许用户通过按下BACK按键返回到前一个Fragment状态                beginTransaction.addToBackStack(null);                beginTransaction.commit();            }        });    }

其中NewInstance方法是在Fragment中实现的一个实例方法,用于将Fragment实例化,通过参数param1的传递能将Activity中的数据传递到Fragment中。通过setArguments()以及getArguments()实现数据从Activity向Fragment传递的目的,如下图所示。

public static Image1Fragment newInstance(String param1) {        Image1Fragment fragment = new Image1Fragment();        //在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法        Bundle args = new Bundle();        args.putString(ARG_PARAM1, param1);        fragment.setArguments(args);        return fragment;    }
@Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getArguments() != null) {            //在Fragment中通过getArguments().getString()获取Activity传来的值            mParam1 = getArguments().getString(ARG_PARAM1);        }    }

6.Fragment与Activity通信

  • Fragment调用Activity里的数据
  在Activity中创建Bundle数据包,并调用Fragment的setArguments(Bundle bundle)方法,此方法在上面的代码中已经介绍了。
  • Activity调用Fragment里的数据
  在Fragment中定义一个内部回调接口,让包含该Fragment的Activity实现该回调接口,这样Fragment可调用该回调方法将数据传递给Activity。下面主要实现在Activity调用Fragment的数据。
先在Fragment中定义一个内部回调接口:
public interface OnFragmentInteractionListener {
public void onFragmentInteraction(String uri); }

在Fragment的onAttach()方法中将Activity转换为OnFragmentInteractionListener接口:

@Override    public void onAttach(Activity activity) {        super.onAttach(activity);        try {            mListener = (OnFragmentInteractionListener) activity;        } catch (ClassCastException e) {            throw new ClassCastException(activity.toString()                    + " must implement OnFragmentInteractionListener");        }    }
private OnFragmentInteractionListener mListener;
if (mListener != null) {
mListener.onFragmentInteraction("需要传递给Activity的值");
 

宿主Activity则需要实现此接口,并重写onFragmentInteraction(String uri)方法,这样就实现了数据从Fragment到Activity的传递:

public class MainActivity extends ActionBarActivity implements Image1Fragment.OnFragmentInteractionListener
@Override public void onFragmentInteraction(String uri) {
TextView tv=(TextView)findViewById(R.id.tt); tv.setText(uri); }

7.效果截图

转载于:https://www.cnblogs.com/TechSnail/p/4712206.html

你可能感兴趣的文章
Linux免密码登陆
查看>>
SpringMVC中文件的上传(上传到服务器)和下载问题(二)--------下载
查看>>
Socket & TCP &HTTP
查看>>
osip及eXosip的编译方法
查看>>
Hibernate composite key
查看>>
[CF Round #294 div2] D. A and B and Interesting Substrings 【Map】
查看>>
keepalived+nginx安装配置
查看>>
我的2015---找寻真实的自己
查看>>
android编译遇到问题修改
查看>>
解决Ubuntu18.04.2远程桌面Xrdp登录蓝屏问题
查看>>
python_封装redis_hash方法
查看>>
《windows程序设计》获取窗口尺寸(05)
查看>>
【重点突破】——Canvas技术绘制音乐播放器界面
查看>>
监控级联时各个层的PoE交换机怎么选?
查看>>
存储过程
查看>>
ADO.NET--SqlConnection、SqlCommand的学习
查看>>
PCA降维处理
查看>>
random模块
查看>>
CSS3 新属性兼容性测试
查看>>
js闭包
查看>>