加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > Asp教程 > 正文

Android开发学习之Fragment介绍

发布时间:2021-11-19 12:23:25 所属栏目:Asp教程 来源:互联网
导读:1.定义 Fragment中文解释是碎片的意思,主要用在大屏幕设备上,例如平板电脑上,支持更加动态和灵活的UI设计。Fragment在你的应用中相当于是一个模块化和可重用的组件,因为Fragment定义了它自己的布局,以及通过使用它自己的生命周期回调方法定义了它自己的

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。
<fragment
         Android:name="ant.snail.com.fragmentactapp.StaticFragment"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:tag="newfrag" />
    这样在宿主Activity中就能看到Fragment了。
 
5.动态加载
 
     上面的静态加载是最基本的方法,下面解析下动态加载的原理。
 
    (1)原理
 
  动态加载,顾名思义是通过代码的方式在Activity中加载Fragment。
 
  通过撰写代码将Fragment添加到一个Activity layout中,这里需要采用Fragment的事务处理(FragmentTransaction),有点类似数据库的事务处理。
 
根据用户的交互情况,对Fragment进行添加、移除、替换,以及执行其他动作,提交给Activity的每一套变化被称作一个事务;
每一个事务都是同时执行一套变化,可以再一个事务中设置你所有想执行的变化,包括add(),remove(),replace(),然后提交给Activity,最后调用commit()方法;
如果允许用户通过按下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文件代码如下:
 
<LinearLayout 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"
    android:orientation="vertical"
    android:gravity="center_horizontal"
    tools:context="ant.snail.com.fragmentactapp.Image1Fragment"
    >
 
    <!-- TODO: Update blank fragment layout -->
 
    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        >
        <TextView
            android:id="@+id/text1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="我是jin兔1"/>
 
        <Button
            android:layout_marginLeft="10dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="传递数据到主窗口"
            android:id="@+id/btfr1" />
 
 
    </LinearLayout>
 
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView1"
        android:src="@drawable/jin1"/>
</LinearLayout>
宿主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.效果截图
 
 
 
本人致力于Web端与移动端的开发与研究,现主要从事GIS相关开发,如WebGIS、移动GIS开发等。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读