Android学习羁绊之Fragment

Fragment是一种可以嵌入在Activity当中的UI片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用得非常广泛。Fragment和Activity十分相似,都能包含布局,都有自己的生命周期。

Fragment使用方式

引用Fragment

新建一个类继承Fragment类,有两个不同包下的Fragment供你选择,一个是系统内置的android.app.Fragment,一个是支持库中的Fragment,系统内置的Fragment无法在所有Android系统版本中保持功能一致性,极不推荐使用(官方已经将系统内置的Fragment标记为过时的类)。推荐支持库中的Fragment:

低版本Android SDK使用support-v4库:
android.support.v4.app.Fragment
由于在高版本Android SDK中,Google官方将support库下的所有类迁移到androidx包下,则使用androidx库:
androidx.fragment.app.Fragment

相关代码如下:

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

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

重写onCreateView()方法,通过LayoutInflater的inflate()方法将要在Fragment中显示的布局加载进来。
在其他布局中引用Fragment:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <fragment
        android:id="@+id/left_fragment"
        android:name="cn.chenjianlink.android.fragmenttest.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

使用<fragment>标签在布局中添加碎片,通过android:name属性来显式指明要添加的碎片类名,需要填入完整路径

动态添加Fragment

    public void replaceFragment(Fragment fragment) {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.right_fragment, fragment);
        fragmentTransaction.commit();
    }

动态添加Fragment分5步:

  1. 创建待添加的Fragment实例
  2. 获取FragmentManager,在Activity中可以直接通过调用getSupportFragmentManager()方法得到
  3. 开启一个事务,通过调用beginTransaction() 方法开启
  4. 向容器内添加或替换Fragment,一般使用replace() 方法实现,需要传入容器的id和待添加的Fragment实例
  5. 提交事务,调用commit() 方法来完成

用Fragment模拟返回栈

FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中。在事务提交之前调用了FragmentTransaction的addToBackStack()方法,它可以接收一个名字用于描述返回栈的状态,一般传入null即可。

Fragment和Activity之间进行通信

为了方便Fragment和Activity之间进行通信,FragmentManager提供了一个类似于findViewById()的方法,专门用于从布局文件中获取Fragment的实例。

MyFragment myFragment = (MyFragment) getSupportFragmentManager().findFragmentById(R.id.my_fragment);

调用FragmentManager的findFragmentById()方法,可以在Activity中得到相应Fragment的实例,然后就能调用Fragment里的方法。

在每个Fragment中都可以通过调用getActivity()方法来得到和当前Fragment相关联的Activity实例。

MainActivity activity = (MainActivity) getActivity();

Fragment中需要使用Context对象时,也可以使用getActivity()方法,因为获取到的Activity本身就是一个Context对象。

基于上述Fragment和Activity的通信方法,可以实现Fragment之间的通信:
在一个Fragment中可以得到与它相关联的Activity,然后再通过这个Activity去获取另外一个Fragment的实例。

Fragment的生命周期

Fragment状态

运行状态

当一个Fragment是可见的,并且它所关联的Activity正处于运行状态时,该Fragment也处于运行状态。

暂停状态

当一个Activity进入暂停状态时(由于另一个未占满屏幕的Activity被添加到了栈顶),与它相关联的可见Fragment就会进入到暂停状态。

停止状态

当一个Activity进入停止状态时,与它相关联的Fragment就会进入到停止状态,或者通过调用FragmentTransaction的remove() 、replace() 方法将Fragment从Activity中移除,但如果在事务提交之前调用addToBackStack()方法,这时的Fragment也会进入到停止状态。进入停止状态的Fragment对用户来说是完全不可见的,有可能会被系统回收。

销毁状态

Fragment总是依附于Activity而存在的,因此当Activity被销毁时,与它相关联的Fragment就会进入到销毁状态。或者通过调用FragmentTransaction的remove() 、replace() 方法将Fragment从Activity中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的Fragment也会进入到销毁状态。

Fragment回调方法

  • onAttach() :当Fragment和Activity建立关联的时候调用。
  • onCreateView() :为Fragment创建视图(加载布局)时调用。
  • onActivityCreated() :确保与Fragment相关联的Activity一定已经创建完毕的时候调用。
  • onDestroyView() :当与Fragment关联的视图被移除的时候调用。
  • onDetach() :当Fragment和Activity解除关联的时候调用。

Fragment完整的生命周期示意图如下:

动态加载布局的技巧

限定符

创建多个layout文件夹,分别在文件夹后添加限定符,系统会根据程序运行的设备屏幕大小加载相应文件夹下的资源(除layout以外,drawable、value、mipmap也可以实现),限定符如下:

最小宽度限定符

最小宽度限定符允许对屏幕的宽度指定一个最小值(以dp为单位),然后以这个最小值为临界点,屏幕宽度大于这个值的设备就加载一个布局,屏幕宽度小于这个值的设备就加载另一个布局。
res文件夹目录:

layout
layout-sw600dp

当程序运行在屏幕宽度大于600dp的设备上时,会加载layout-sw600dp文件夹中的布局,当程序运行在屏幕宽度小于600dp的设备上时,则仍然加载默认的layout文件夹中的布局

全部评论

相关推荐

07-09 18:28
门头沟学院 Java
写着提前批,结果还要实习4个月以上???
程序员牛肉:这种不用看,直接投了,面试的时候问对应的HR就行。有可能他们是直接复制的暑期实习的模板。
点赞 评论 收藏
分享
07-09 18:33
门头沟学院 Java
这么逆天每年都有人去???&nbsp;填多益网申就是大型的服从性测试
鲁大牛:辅导员在群里发了这个公司我就申了一下。网申居然要写当场开摄像头写两篇不少于三百字的作文。太逆天了
点赞 评论 收藏
分享
每晚夜里独自颤抖:你cet6就cet6,cet4就cet4,你写个cet证书等是什么意思。专业技能快赶上项目行数,你做的这2个项目哪里能提现你有这么多技能呢
点赞 评论 收藏
分享
认真搞学习:28小登的建议,投算法岗不要写什么物理竞赛,互联网+,多写点项目,用什么算法做了什么。还有本科算法是不可能的开发你这个也没有项目啊
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-09 16:15
我应届生,去年10月份开始在这家公司实习,到今年10月份正好一年想(实习+试用期),在想要不要提前9月份就离职,这样好找工作些,但又差一个月满一年,又怕10月份国庆回来离职,容易错过了下半年的金九银十,到年底容易gap到年后
小破站_程序员YT:说这家公司不好吧,你干了快一年 说这家公司好吧,你刚毕业就想跑路说你不懂行情吧,你怕错过金九银十说 你懂行情吧,校招阶段在实习,毕业社招想换工作 哥们,我该怎么劝你留下来呢
应届生,你找到工作了吗
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务