Fragment的基本用法、Fragment和活动间的通信、Fragment的生命周期、动态加载布局的技巧

news2024/11/28 14:45:19

一、Fragment的简单用法

1、制作Fragment

1.1 新建一个布局文件left_fragment.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:id="@+id/Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="Button"/>


</LinearLayout>

1.2 新建一个LeftFragment类继承Fragment

public class LeftFragment extends Fragment {

    LeftFragmentBinding binding;
    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        /**
         * 普通写法:
         *  View view = inflater.inflate(R.layout.left_fragment,container,false);
         *  retuen view;
         *  不需要重写onDestroyView
         */

        binding = LeftFragmentBinding.inflate(inflater,container,false);
         return binding.getRoot();
    }

    public void f(){
        Log.d("F","SSS");
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        binding = null;
    }
}

重写onCreateView方法。

因为要保持binding的生命周期在有效范围内,所以需要在onDestroy中让binding=null

1.3 在布局文件activity_main.xml加载这个碎片

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <fragment
        android:id="@+id/Leftfragment"
        android:name="com.example.fragment.LeftFragment"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"/>

</LinearLayout>

使用android:name指定加载的类,注意需要有完整的包名。

2、动态加载Fragment

2.1 新建一个用于替换的布局文件

新建一个用于替换的布局文件,another_left_fragment.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:background="#ffff00"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="24sp"
        android:text="This is Fragment"/>

</LinearLayout>

2.2 新建一个AnotherLeftFragment类继Fragment

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

3.3 在MainActivity中动态替换

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        //获取FragmentManager实例,通过向下转型为LeftFragment
        LeftFragment leftFragment = (LeftFragment) getSupportFragmentManager().findFragmentById(R.id.Leftfragment);

        //调用button按钮的监听器
        leftFragment.binding.Button.setOnClickListener(this);


    }


    @Override
    public void onClick(View view) {
        int Id = view.getId();
        if(Id == R.id.Button){

            /**
             * 匿名替换的方式:
             *  getSupportFragmentManager().beginTransaction().replace(R.id.Leftfragment,new AnotherRightFragment()).commit();
             */

            replaceFragment(new AnotherRightFragment());
        }
    }

    private void replaceFragment(Fragment fragment){
        //1、获取FragmentManager实例
        FragmentManager fragmentManager = getSupportFragmentManager();

        //2、开启一个事物
        FragmentTransaction transaction = fragmentManager.beginTransaction();

        //3、向指定名称Id的容器内替换碎片实例
        transaction.replace(R.id.Leftfragment,fragment);

        //4、提交事物
        transaction.commit();

    }
}

image-20230724103310754

3、在碎片中模拟返回栈

我们成功实现了向活动中动态添加碎片的功能,不过尝试一下就会发现,通过点击按钮添加了一个碎片之后,这时按下Back键程序就会直接退出。如果这里我们想模仿类似于返回栈的效果,按下Bck键可以回到上一个碎片,该如何实现呢?其实很简单FragmentTransaction中提供了一个addToBackStack()方法,可以用于将一个事务添加到返回栈中,修改MainActivity中的代码,如下所示:

private void replaceFragment(Fragment fragment){
    //获取FragmentManager实例
    FragmentManager fragmentManager = getSupportFragmentManager();

    //开启一个事物
    FragmentTransaction transaction = fragmentManager.beginTransaction();

    //向指定名称Id的容器内替换碎片实例
    transaction.replace(R.id.Rightfragment,fragment);

    //添加返回栈
    transaction.addToBackStack(null);

    //提交事物
    transaction.commit();

}

4、Fragment和活动间的通信

4.1 从Activit中获取Fragment

其实我们已经用过很多次了,就是先获取LeftFragment的实例,如何通过实例中的binding访问Button的行为,这就是获取一个碎片,如何调用碎片中的方法。

        //获取FragmentManager实例,通过向下转型为LeftFragment
        LeftFragment leftFragment = (LeftFragment) getSupportFragmentManager().findFragmentById(R.id.Leftfragment);

4.2 从Fragment中获得Activit

使用getActivit即可,因为获得的活动本身就是一个Context对象

MainActivit activit = (MainActivit) getActivit();

二、Fragment的生命周期

1、Fragment的四种状态和回调

状态:

  • 运行状态:当一个碎片是可见的,并且它所关联的活动正处于运行状态时,该碎片也处于运行状态。
  • 暂停状态:当一个活动进人暂停状态时(由于另一个未占满屏幕的活动被添加到了栈顶),与它相关联的可见碎片就会进人到暂停状态。
  • 停止状态:当一个活动进入停止状态时,与它相关联的碎片就会进入到停止状态,或者通过调用FragmentTransactionremove()replace()方法将碎片从活动中移除,但如果在事务提交之前调用addToBackStack()方法,这时的碎片也会进入到停止状态。
  • 销毁状态:碎片总是依附于活动而存在的,因此当活动被销毁时,与它相关联的碎片就会进人到销毁状态。或者通过调用FragmentTransaction的remove()、replace()方法将碎片从活动中移除,但在事务提交之前并没有调用addToBackStack()方法,这时的碎片也会进人到销毁状态。

回调方法:

  • onAttach():当活动和碎片建立关联时使用
  • OnCreateView:当为碎片创建视图时使用
  • onActivityCreated():确保与碎片相关联的活动一定已经创建完毕的时候调用。
  • onDestroyView()。当与碎片关联的视图被移除的时候调用。
  • onDetach()。当碎片和活动解除关联的时候调用。

2、Fragment的生命周期

image-20230724152229156
旧版生命周期如下:

image-20230724174228687
打开一个碎片生命周期的调用情况:
image-20230724174457561

一般**onCreateView()**用于初始化Fragment的视图,**onViewCreated()一般用于初始化视图内各个控件,而onCreate()**用于初始化与Fragment视图无关的变量。

另外值得一提的是,在碎片中你也是可以通过onSaveInstanceState()方法来保存数据的,因为进入停止状态的碎片有可能在系统内存不足的时候被回收。保存下来的数据在onCreate()onCreateview()onActivityCreated()这3个方法中你都可以重新得到,它们都含有一个Bundle类型的savedInstanceState参数。

三、动态加载布局的技巧

1、使用限定符

Android Studio中res下创建layout-large

版本:Android Studio Flamingo | 2022.2.1 Patch 2

在res右键Android resource file,resource type选择layout,available qualifiers选择Size,在右侧chosen qualifiers选择large,最后输入file name,新建成功,这样在res目录下自动新建layout-large文件夹,并在文件夹中生成刚输入的file name的布局文件

image-20230724130644928

image-20230724130927237

常见限定符参考表:

image-20230724131543244

2、使用最小限定符

最小宽度限定符允许我们对屏幕的宽度指定一个最小值(以中为单位),然后以这个最小值为临界点,屏幕宽度大于这个值的设备就加载一个布局,屏幕宽度小于这个值的设备就加载另一个布局。

image-20230724132302594

image-20230724132318762

这就意味着,当程序运行在屏幕宽度大于600dp的设备上时,会加载layout–sw600 dp/activity main布局,当程序运行在屏幕宽度小于600dp的设备上时,则仍然加载默认的layout/activity main布局。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/793293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【小白必看】轻松获取王者荣耀英雄皮肤图片的Python爬虫程序

文章目录 前言项目运行效果图导入模块和库伪装请求头获取英雄列表遍历英雄列表创建英雄目录访问英雄主页并解析HTML代码获取皮肤名称下载皮肤图片完整代码总结 前言 当谈到王者荣耀游戏时&#xff0c;无法忽视的是其丰富多样的英雄皮肤。这些皮肤不仅为玩家提供了个性化的游戏…

文本预处理——文本特征处理

目录 文本特征处理n-gram特征文本长度规范 文本特征处理 n-gram特征 文本长度规范

《面试1v1》Kafka消息是采用Pull还是Push模式

&#x1f345; 作者简介&#xff1a;王哥&#xff0c;CSDN2022博客总榜Top100&#x1f3c6;、博客专家&#x1f4aa; &#x1f345; 技术交流&#xff1a;定期更新Java硬核干货&#xff0c;不定期送书活动 &#x1f345; 王哥多年工作总结&#xff1a;Java学习路线总结&#xf…

(学习笔记-硬件结构)CPU如何执行程序?

冯诺依曼模型 冯诺依曼模型主要由五部分组成&#xff1a;运算器、控制器、存储器、输入设备、输出设备。 控制器&#xff08;Control Unit&#xff09;&#xff1a;从内存中取指令、翻译指令、分析指令&#xff0c;然后根据指令的内存向有关部件发送控制命令&#xff0c;控制相…

E2E工程问题:小周期转大周期Gateway

摘要&#xff1a; 本文讨论一个具体的工程问题&#xff0c;E2E报文对应的信号&#xff0c;由小周期转大周期导致的E2E校验失败问题。 工程中&#xff0c;网关节点很重要的一个功能就是路由。当然&#xff0c;E2E&#xff08;End to End&#xff09;报文也可路由&#xff0c;但…

webpack xxx is not a constructor

环境 webpack5.88.2 vue-router 按需引入 原因 模块循环引用导致 有A B C三个模块 A B模块import C 中导出的class c又依赖B 中Class 的方法 B 又依赖C中的class 此时会导致import 的 C 为undefined

求求你,别这样写简历,我要是HR连面试机会都不给你,别说我没告诉你!

前言 我作为部门的面试官&#xff0c;在此期间也收获了不少简历。但可惜的是&#xff0c;收到的简历数量虽多&#xff0c;但令人中意的却是凤毛菱角&#xff0c;一些应聘者倒不是因为自身能力不足而无法进入面试环节&#xff0c;而是简历本身就没有很好的展示出自己的能力&…

苍穹外卖 Spring Task 来单提醒 催单Apache ECharts day10~11

苍穹外卖-day10 课程内容 Spring Task订单状态定时处理WebSocket来单提醒客户催单 功能实现&#xff1a;订单状态定时处理、来单提醒和客户催单 订单状态定时处理&#xff1a; 来单提醒&#xff1a; 客户催单&#xff1a; 1. Spring Task 1.1 介绍 Spring Task 是Spring框架提供…

k8s中强制删除pv

K8s 集群内有一个已经不再使用的 PV&#xff0c;虽然已经删除了与其关联的 Pod 及 PVC&#xff0c;并对其执行了删除命令&#xff0c;但仍无法正常删除&#xff0c;一直处于 Terminating 状态&#xff1a; 解决办法&#xff1a; 1. 获取pv信息 kubectl get pv 2. 解除pv锁定 …

k8s: kubectl: logs: rotate 问题

https://kubernetes.io/docs/concepts/cluster-administration/logging/ 当kubenet存放container的日志满了的时候&#xff0c;会发生rotate&#xff0c;当rotate发生的时候&#xff0c;是由kubectl logs 这个命令可能会出现以下两个问题&#xff1a; https://github.com/kuber…

30-使用RocketMQ做削峰处理

1、增加排队功能的思路 在出票模块里,一个消费者拿到了某个车次锁,则该车次下所有的票都由他来出,一张一张的出,知道所有的订单都出完。 2、实现排队出票功能 2.1、 修改发送到MQ消息的内容 修改MQ消息内容,只需要通知出哪天和哪个车次的票(即:组成锁的内容),不需要…

网络安全系统中的守护者:如何借助威胁情报 (TI) 提高安全性

在这篇哈巴尔网站上的推文中&#xff0c;我们将解释 TI 缩写背后的含义、为什么需要它、Positive Technologies 收集哪些网络威胁数据以及如何帮助企业预防网络威胁。我们将以四种情况为例&#xff0c;说明公司如何使用 PT Threat Intelligence Feeds 来发现恶意活动并预防攻击…

2023-07-26 LeetCode每日一题(更新数组后处理求和查询)

2023-07-26每日一题 一、题目编号 2569. 更新数组后处理求和查询二、题目链接 点击跳转到题目位置 三、题目描述 给你两个下标从 0 开始的数组 nums1 和 nums2 &#xff0c;和一个二维数组 queries 表示一些操作。总共有 3 种类型的操作&#xff1a; 操作类型 1 为 querie…

uni-app点击按钮弹出提示框(以弹窗的形式显示),选择确定和取消

学习目标&#xff1a; 学习目标如下所示&#xff1a; uni-app点击提交按钮后弹出提示框&#xff0c;&#xff08;以弹窗的形式显示&#xff09;,提示用户是否确认提交&#xff08;即确定和取消&#xff09;&#xff0c;点击确定后调用真正的提交方法&#xff0c;将数据传给后端…

进程虚拟地址空间区域划分

目录 图示 详解 代码段 备注&#xff1a;x86 32位linux环境下&#xff0c;进程虚拟地址空间区域划分 图示 详解 用户空间 用于存储用户进程代码和数据&#xff0c;只能由用户进程访问 内核空间 用于存储操作系统内核代码和数据&#xff0c;只能由操作系统内核访问 text t…

SpringBoot实战(二十三)集成 SkyWalking

目录 一、简介二、拉取镜像并部署1.拉取镜像2.运行skywalking-oap容器3.运行skywalking-ui容器4.访问页面 三、下载解压 agent1.下载2.解压 四、创建 skywalking-demo 项目1.Maven依赖2.application.yml3.DemoController.java 五、构建启动脚本1.startup.bat2.执行启动脚本3.发…

攻防世界-Reverse-re1

题目描述&#xff1a;菜鸡开始学习逆向工程&#xff0c;首先是最简单的题目 下载附件&#xff0c;执行程序&#xff0c;如下界面 1. 思路分析 没啥说的&#xff0c;既然题目都说是一道简单的逆向题&#xff0c;那么直接使用ida逆向即可&#xff0c;看逆向出的结果是否能写入到…

Cesium态势标绘专题-矩形(标绘+编辑)

标绘专题介绍:态势标绘专题介绍_总要学点什么的博客-CSDN博客 入口文件:Cesium态势标绘专题-入口_总要学点什么的博客-CSDN博客 辅助文件:Cesium态势标绘专题-辅助文件_总要学点什么的博客-CSDN博客 本专题没有废话,只有代码,代码中涉及到的引入文件方法,从上面三个链…

tensorRT多batch动态推理

tensorRT的多batch推理&#xff0c;导出的onnx模型必须是动态batch&#xff0c;只需在导出的时候&#xff0c;设置一个dynamic_axis参数即可。 torch.onnx.export(hybrik_model, dummy_input, "./best_model.onnx", verboseTrue, input_namesinput_names, \output_…

【Vue3基础】组合事件配合v-model、watch的使用

一、需求描述 在组合事件中&#xff0c;实现在子事件输入框中输入使父事件实时显示输入内容 二、代码参考 1、关注文件&#xff0c;在App中嵌套Main&#xff0c;在Main中嵌套searchDemo 2、Main.vue文件 <template><h3>Main页面</h3><p>搜索内容为…