当前位置: 首页 > news >正文

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

一、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"><Buttonandroid: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@Overridepublic 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");}@Overridepublic 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"><fragmentandroid: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"><TextViewandroid: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@Overridepublic 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{@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//获取FragmentManager实例,通过向下转型为LeftFragmentLeftFragment leftFragment = (LeftFragment) getSupportFragmentManager().findFragmentById(R.id.Leftfragment);//调用button按钮的监听器leftFragment.binding.Button.setOnClickListener(this);}@Overridepublic 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实例,通过向下转型为LeftFragmentLeftFragment 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.lryc.cn/news/97605.html

相关文章:

  • 机器学习 day30(正则化参数λ对模型的影响)
  • 图文教程:如何在 3DS Max 中创建3D迷你卡通房屋
  • 根据UIL下载图片/视频、根据URL自动下载图片/视频、GUI自动下载想要的图片
  • HTML <picture> 标签
  • 力扣天天练--week3-LeetCode75
  • 5.2 方法的定义和调用
  • Linux基础以及常用命令
  • echarts 折线图上只显示某一个点值
  • 1、传统锁回顾(Jvm本地锁,MySQL悲观锁、乐观锁)
  • 【Java||牛客】DFS应用迷宫问题
  • 【vue】Vue中class样式的动态绑定
  • 机器学习深度学习——随机梯度下降算法(及其优化)
  • 【MTK平台】【wpa_supplicant】关于wpa_supplicant_8/src/p2p/p2p.c文件的介绍
  • 华为数通HCIP-流量过滤与转发路径控制
  • SpringBoot中定时任务开启多线程避免多任务堵塞
  • 回归预测 | MATLAB实现SO-CNN-BiLSTM蛇群算法优化卷积双向长短期记忆神经网络多输入单输出回归预测
  • 入侵检测——IDS概述、签名技术
  • golang 标准库json Marshal 序列化与反序列化
  • 【【51单片机AD/DA的分析】】
  • 在docker中安装使用达梦数据库
  • Leetcode-每日一题【剑指 Offer II 010. 和为 k 的子数组】
  • 【JavaScript】使用Promise来处理异步调用,方法传入参数为接口,并回调接口的方法
  • grid map学习笔记1之Ubuntu18.04+ROS-melodic编译安装grid_map栅格地图及示例运行
  • postgres wal2json插件jsonb字段数据丢失问题解决
  • 华为eNSP:路由引入
  • Retrospectives on the Embodied AI Workshop(嵌入式人工智能研讨会回顾) 论文阅读
  • 「JVM」Full GC和Minor GC、Major GC
  • Asp.Net MVC 使用Log4Net
  • [元带你学: eMMC协议 29] eMMC 断电通知(PON) | 手机平板电脑断电通知
  • vue使用recorder-core.js实现录音功能