fragment基本使用

    科技2022-07-12  147

    fragment基本使用

    初识碎片(片段)Fragments | Android Developersfragment的特点 Fragment的简单用法布局文件添加界面在activity中添加fragment Fragment的动态加载新建fragment_new.xml和NewFragment.java利用FrameLayout加载将NewFragment载入FrameLayout 在碎片中模拟返回栈碎片和活动之间的通信

    初识碎片(片段)

    Fragments | Android Developers

    Fragment 表示 FragmentActivity 中的行为或界面的一部分。您可以在一个 Activity 中组合多个碎片,从而构建多窗格界面,并在多个 Activity 中重复使用某个碎片。您可以将碎片视为 Activity 的模块化组成部分,它具有自己的生命周期,能接收自己的输入事件,并且您可以在 Activity 运行时添加或移除片段。 碎片必须始终托管在 Activity 中,其生命周期直接受宿主 Activity 生命周期的影响。

    fragment不能独立存在,必须依赖于activity一个activity可以有多个fragment,一个fragment可以被多个activity重复调用fragment有自己的生命周期,可以接受输入事件

    fragment的特点

    模块化

    Android 在 Android 3.0(API 级别 11)中引入了碎片,主要目的是为大屏幕(如平板电脑)上更加动态和灵活的界面设计提供支持。 例如,新闻应用可以使用一个片段在左侧显示文章列表,使用另一个片段在右侧显示文章。

    可重用 一个activity可以有多个fragment,一个fragment可以被多个activity重复调用可适配 模块化碎片可以更改片段的组合方式,适应不同的屏幕尺寸—图1

    Fragment的简单用法

    步骤

    定义xml布局文件自定义myFragment子类继承自Fragment,实现onCreate()方法在Activity中调用setContentView()来加载布局文件

    我们在一个activity中添加两个fragment,下面来看看具体如何实现吧(参考《第一行代码》哟) 新建两个java文件,分别命名为LeftFragment和RightFragment

    布局文件

    新建一个左侧布局fragment_left.xml,放一个按钮

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="只是个button" android:textAllCaps="false" android:layout_gravity="center_horizontal" /> </LinearLayout>

    那么右边也是一样的,新建一个fragment_right.xml,放一个TextView好了,跟上面的差不多啦。然后为了区分这两个fragment,我们把right这个布局设置一个背景颜色。

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="#E8CCFF" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:padding="20dp" android:text="给点颜色看看" android:layout_gravity="center_horizontal" /> </LinearLayout>

    添加界面

    Fragment 类的代码与 Activity 非常相似。它包含与 Activity 类似的回调方法,如 onCreate()、onStart()、onPause() 和 onStop()。

    那我们现在可以在一开始新建的LeftFragment.java中编辑。

    继承Fragment类。 这时候如果有两个包下的Fragment可以选择,那就使用support包的Fragment(app包的 )重写onCreateView()方法 public class LeftFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater,,ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.left_fragment, container, false); return view; } }

    返回布局,onCreateView() 提供了一个 LayoutInflater 对象。 传递至 onCreateView() 的 container 参数是布局将插入到的父级 ViewGroup(来自 Activity 的布局)。 savedInstanceState 参数是在恢复fragment时,提供上一片段实例相关数据的 Bundle(处理片段生命周期部分对恢复状态做了详细阐述)。

    inflate() 方法带有三个参数: 您想要扩展的布局的资源 ID。 将作为扩展布局父项的 ViewGroup。container。 ViewGroup的布尔值在本例中为 false,因为系统已将扩展布局插入 container,而传递 true值会在最终布局中创建一个多余的视图组。

    那么RightFragment的布局绑定也是一样,自己修改一下就好啦。

    在activity中添加fragment

    我们在activity的布局文件中添加了碎片,要注意的是这里需要通过android:name属性来指明要添加的碎片类名。

    <?xml version="1.0" encoding="utf-8"?> <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="horizontal" tools:context=".MainActivity"> <fragment android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:name="com.example.fragmenttest.LeftFragment" android:id="@+id/left_fragment" /> <fragment android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:name="com.example.fragmenttest.RightFragment" android:id="@+id/right_fragment" /> </LinearLayout>

    好啦,写到这里,你就可以运行一下程序,看看你自己完成的简单碎片效果啦!


    Fragment的动态加载

    上文所说的静态添加碎片还不够厉害,接下来我们介绍fragment的动态添加方法,可以在程序运行时动态地添加到活动当中呢!那我们就打开刚刚的项目,在里面继续完善吧。

    新建fragment_new.xml和NewFragment.java

    新建fragment_new.xml 放一个TextView 换一个背景颜色,区分一下这是一个新的碎片。

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:background="#99BBFF" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="this is a new fragment" android:padding="20dp" android:layout_gravity="center_horizontal" /> </LinearLayout>

    新建NewFragment.java 和上面的LeftFragment一样,在onCreateView中通过LayoutInflater来绑定布局。

    public class NewFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ View view = inflater.inflate(R.layout.fragment_new,container,false); return view; } }

    以上代码,我们就准备好了一个新的碎片来动态添加了。

    利用FrameLayout加载

    FrameLayout是帧布局,是六大布局中最简单的一个。

    线性布局(LinearLayout):按照垂直或者水平方向布局的组件

    帧布局(FrameLayout):组件从屏幕左上方布局组件

    表格布局(TableLayout):按照行列方式布局组件

    绝对布局(AbsoluteLayout):按照绝对坐标来布局组件

    相对布局(RelativeLayout):相对其它组件的布局方式

    约束布局 (ConstraintLayout):按照约束布局组件,解决布局嵌套过多的问题

    但是帧布局没有定位方式,所添加的控件都会挤到左上角。同一时刻只能看到最上面的控件,后续添加的控件会覆盖前一个。 而我们在activity_main.xml中,只是简单地在布局里放一个碎片,不需要任何定位和嵌套,所以我们在这里使用帧布局。

    <?xml version="1.0" encoding="utf-8"?> <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="horizontal" tools:context=".MainActivity"> <fragment android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:name="com.example.fragmenttest.LeftFragment" android:id="@+id/left_fragment" /> <!-- <fragment--> <!-- android:layout_width="0dp"--> <!-- android:layout_height="match_parent"--> <!-- android:layout_weight="1"--> <!-- android:name="com.example.fragmenttest.RightFragment"--> <!-- android:id="@+id/right_fragment" />--> <FrameLayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:id="@+id/right_layout" > </FrameLayout> </LinearLayout>

    我们把原本的right_fragment注释掉,改成FrameLayout,id属性命名为为right_layout

    将NewFragment载入FrameLayout

    修改完布局,我们就来修改java文件啦。 先打开MainActivity,用implements声明自己使用的接口。

    extends 继承某个类, 继承之后可以使用父类的方法, 也可以重写父类的方法 implements实现多个接口, 接口的方法重写后才能使用

    实例化button,给他注册一个点击事件。 改写button的onClick方法用到了switch case。点击左侧碎片中的button时,会调用replaceFragment()方法将右侧碎片替换成NewFragment。 在replaceFragment方法中,从FragmentManager中传递一个碎片给FragmentTransaction,将新的right_layout布局替换到Framelayout中。

    public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(this); replaceFragment(new RightFragment()); } @Override public void onClick(View v){ switch(v.getId()){ case R.id.button: replaceFragment(new NewFragment()); break; default: break; } } private void replaceFragment(Fragment fragment){ FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.replace(R.id.right_layout,fragment); transaction.commit(); } }

    也就是说,动态添加碎片主要分成以下5步:

    创建待添加的碎片实例直接调用getSupportFragmentManager()方法 获取FragmentManager通过beginTransaction() 开启一个事务利用replace()方法 向容器内添加或者替换碎片,需要传入容器的id和碎片实例。利用commit()方法提交事务

    在碎片中模拟返回栈

    也就是返回到之前的上一个碎片。如果直接在上面的代码下执行的程序点击返回键,哎呀怎么直接退出了??如果我想让他回到之前的状态要怎么办呢? 这个时候我们只需要在上面写的提交事务方法commit()之前,调用一个addToBackStack()方法即可,通常传入null。

    private void replaceFragment(Fragment fragment){ FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.replace(R.id.right_layout,fragment); transaction.addToBackStack(null); transaction.commit();

    这个时候再执行程序,你就会发现,点击back是回到了之前的RightFragment的页面,而不是直接退出程序啦。

    碎片和活动之间的通信

    碎片都是嵌入活动显示的,那么如果我们想要在活动中调用碎片,或者在碎片中调用活动,应该如何实现? FragmentManager提供了findFragnentById()方法,专门用于从布局中获取碎片的实例。(类似于findViewById()) 在碎片中调用活动可以通过getAvtivity()实现,获取到的活动实例是一个context对象。 碎片和碎片之间的通信就可以通过与他们相关联的活动来联系。这里只是简单介绍一下最基本的方法,想要继续了解的同学可以自己看看相关博客呀!


    本文参考自《第一行代码》和Android developer官网https://developer.android.com/guide/components/fragments#java

    继续了解: Java抽象类与接口https://blog.csdn.net/weixin_43547832/article/details/101302526 Java继承https://blog.csdn.net/weixin_43312313/article/details/99716504 安卓六大布局https://www.jianshu.com/p/a567c5cf8e1a


    课后作业:有时间的同学可以看《第一行代码》里第四章碎片的实践——实现新闻列表,不强制要求完成,你也可以应用到你的冬令营作品中!期待大家优秀的冬令营作品呀!

    Processed: 0.013, SQL: 8