使用supportFragmentManager管理多个fragment切换

android studio创建的项目就没有一个简单点的框架,生成的代码都是繁琐而复杂,并且不实用。

国内的页面一般都是TAB页面的比较多,老外更喜欢侧边菜单。

如果我们使用一个activity来创建程序,来用占位符管理多个fragment切换,这里水一篇最简单直接的做法。
源码:
https://download.csdn.net/download/robinfoxnan/89485371?spm=1001.2014.3001.5503

预览:https://img-blog.csdnimg.cn/direct/e38ca75c7a694b049366ef05da984ef6.jpeg

Description of image
## **1. Java**实现

在 Android 开发中,使用 FragmentManager 来管理多个 Fragment 页面是一个常见的做法。可以通过以下步骤在主页面的占位符上替换多个 Fragment

  1. 创建主 Activity 布局:在你的主 Activity 布局文件中,创建一个 FrameLayout 作为占位符,用于显示 Fragment

    <!-- activity_main.xml -->
    <FrameLayoutandroid:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="match_parent" />
    
  2. 创建 Fragments:创建多个 Fragment,每个 Fragment 都有自己的布局和逻辑。

    // ExampleFragment.java
    public class ExampleFragment extends Fragment {@Nullable@Overridepublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.fragment_example, container, false);}
    }
    
    <!-- fragment_example.xml -->
    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- Fragment content goes here --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Example Fragment" />
    </LinearLayout>
    
  3. 在主 Activity 中管理 Fragments:在你的主 Activity 中使用 FragmentManager 来替换占位符中的 Fragment

    // MainActivity.java
    public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 默认加载的 Fragmentif (savedInstanceState == null) {getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new ExampleFragment()).commit();}}// 用于切换 Fragment 的方法public void switchFragment(Fragment fragment) {getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, fragment).addToBackStack(null).commit();}
    }
    
  4. 切换 Fragment:在主 Activity 中调用 switchFragment 方法来切换不同的 Fragment

    // 切换到另一个 Fragment
    switchFragment(new AnotherFragment());
    

通过这种方式,你可以在主页面的占位符上动态替换多个 Fragment 页面。你可以根据需要在不同的事件(如按钮点击)中调用 switchFragment 方法来切换不同的 Fragment

2.kotlin实现

2.1 添加基础切换流程

下面是用 Kotlin 实现上述功能的步骤:

  1. 创建主 Activity 布局:在你的主 Activity 布局文件中,创建一个 FrameLayout 作为占位符,用于显示 Fragment

    <!-- activity_main.xml -->
    <FrameLayoutandroid:id="@+id/fragment_container"android:layout_width="match_parent"android:layout_height="match_parent" />
    
  2. 创建 Fragments:创建多个 Fragment,每个 Fragment 都有自己的布局和逻辑。

    // ExampleFragment.kt
    class ExampleFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_example, container, false)}
    }
    
    <!-- fragment_example.xml -->
    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- Fragment content goes here --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Example Fragment" />
    </LinearLayout>
    
  3. 在主 Activity 中管理 Fragments:在你的主 Activity 中使用 FragmentManager 来替换占位符中的 Fragment

    // MainActivity.kt
    class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 默认加载的 Fragmentif (savedInstanceState == null) {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, ExampleFragment()).commit()}}// 用于切换 Fragment 的方法fun switchFragment(fragment: Fragment) {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).addToBackStack(null).commit()}
    }
    
  4. 切换 Fragment:在主 Activity 中调用 switchFragment 方法来切换不同的 Fragment

    // 切换到另一个 Fragment
    switchFragment(AnotherFragment())
    

通过这种方式,可以在主页面的占位符上动态替换多个 Fragment 页面。你可以根据需要在不同的事件(如按钮点击)中调用 switchFragment 方法来切换不同的 Fragment

2.2 页面中获取主界面

AnotherFragment 中获取 MainActivity 的实例并调用 switchFragment 方法,你可以使用 Kotlin 的 activity 属性,它返回当前 Fragment 所附着的 Activity 实例。你需要确保类型转换安全,避免强制转换引起的异常。

下面是一个示例:

  1. 创建 AnotherFragment:在 AnotherFragment 中编写逻辑来获取 MainActivity 实例并调用 switchFragment 方法。

    // AnotherFragment.kt
    class AnotherFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_another, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 假设你有一个按钮来触发 Fragment 切换val button: Button = view.findViewById(R.id.switch_fragment_button)button.setOnClickListener {(activity as? MainActivity)?.switchFragment(ExampleFragment())}}
    }
    
    <!-- fragment_another.xml -->
    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- Fragment content goes here --><Buttonandroid:id="@+id/switch_fragment_button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Switch to Example Fragment" />
    </LinearLayout>
    
  2. 更新 MainActivity:确保 MainActivity 里有一个方法 switchFragment 可以被调用。

    // MainActivity.kt
    class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)// 默认加载的 Fragmentif (savedInstanceState == null) {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, ExampleFragment()).commit()}}// 用于切换 Fragment 的方法fun switchFragment(fragment: Fragment) {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment).addToBackStack(null).commit()}
    }
    

通过这种方式,你可以在 AnotherFragment 中获取 MainActivity 的实例并调用 switchFragment 方法来切换 Fragment。这利用了 Kotlin 的安全类型转换 (as?) 来确保在类型转换失败时返回 null,而不是引发异常。

2.3 复用fragment

每次调用 switchFragment 方法时,都会创建一个新的 Fragment 实例并替换当前的 Fragment。如果你希望在切换 Fragment 时复用已有的 Fragment 实例,而不是每次都创建一个新的,可以在 MainActivity 中维护这些 Fragment 的实例。

下面是一个示例,展示如何在 MainActivity 中维护 Fragment 实例,并在切换时复用这些实例:

  1. MainActivity 中维护 Fragment 实例

    // MainActivity.kt
    class MainActivity : AppCompatActivity() {private lateinit var exampleFragment: ExampleFragmentprivate lateinit var anotherFragment: AnotherFragmentoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)if (savedInstanceState == null) {// 初始化 Fragment 实例exampleFragment = ExampleFragment()anotherFragment = AnotherFragment()// 默认加载的 FragmentsupportFragmentManager.beginTransaction().replace(R.id.fragment_container, exampleFragment).commit()} else {// 恢复已存在的 Fragment 实例exampleFragment = supportFragmentManager.findFragmentByTag("ExampleFragment") as ExampleFragmentanotherFragment = supportFragmentManager.findFragmentByTag("AnotherFragment") as AnotherFragment}}// 用于切换 Fragment 的方法fun switchFragment(fragment: Fragment, tag: String) {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, fragment, tag).addToBackStack(null).commit()}
    }
    
  2. AnotherFragment 中调用 switchFragment 方法

    // AnotherFragment.kt
    class AnotherFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_another, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 假设你有一个按钮来触发 Fragment 切换val button: Button = view.findViewById(R.id.switch_fragment_button)button.setOnClickListener {(activity as? MainActivity)?.switchFragment((activity as MainActivity).exampleFragment, "ExampleFragment")}}
    }
    

通过这种方式,你可以在 MainActivity 中维护 Fragment 的实例,并在切换时复用这些实例,而不是每次都创建一个新的 Fragment。在调用 switchFragment 方法时,通过传递 Fragment 实例和对应的标签(tag)来替换当前的 Fragment

2.4 map来管理多个fragment

可以使用一个 Map 来管理多个 Fragment 实例。这可以使得管理 Fragment 的实例更加灵活和高效。你可以在 MainActivity 中使用 Map 来存储 Fragment 实例,并在需要切换 Fragment 时从 Map 中获取相应的实例。

以下是一个示例,展示如何使用 Map 来管理多个 Fragment 实例:

  1. MainActivity 中定义一个 Map 来存储 Fragment 实例

    // MainActivity.kt
    class MainActivity : AppCompatActivity() {private val fragmentMap = mutableMapOf<String, Fragment>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)if (savedInstanceState == null) {// 初始化 Fragment 实例并存储到 Map 中fragmentMap["ExampleFragment"] = ExampleFragment()fragmentMap["AnotherFragment"] = AnotherFragment()// 默认加载的 FragmentswitchFragment("ExampleFragment")}}// 用于切换 Fragment 的方法fun switchFragment(tag: String) {val fragment = fragmentMap[tag]fragment?.let {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, it, tag).addToBackStack(null).commit()}}
    }
    
  2. AnotherFragment 中调用 switchFragment 方法

    // AnotherFragment.kt
    class AnotherFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_another, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 假设你有一个按钮来触发 Fragment 切换val button: Button = view.findViewById(R.id.switch_fragment_button)button.setOnClickListener {(activity as? MainActivity)?.switchFragment("ExampleFragment")}}
    }
    
  3. ExampleFragment 中调用 switchFragment 方法(类似 AnotherFragment

    // ExampleFragment.kt
    class ExampleFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_example, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 假设你有一个按钮来触发 Fragment 切换val button: Button = view.findViewById(R.id.switch_fragment_button)button.setOnClickListener {(activity as? MainActivity)?.switchFragment("AnotherFragment")}}
    }
    

通过这种方式,你可以使用一个 Map 来管理多个 Fragment 实例,并在需要时通过标签(tag)来切换 Fragment。这使得 Fragment 的管理更加灵活和高效。

2.5 使用库模块中的界面

当然可以!在 Android 项目中,你可以导入其他模块或库,并在你的应用中使用它们定义的 Fragment。以下是一个示例,展示如何导入一个模块并使用该模块中定义的 Fragment

假设你有一个名为 mylibrary 的模块,其中定义了一个 CustomFragment

  1. 在你的项目中导入模块

    首先,确保你的项目的 settings.gradle 文件中包含了该模块:

    include ':app', ':mylibrary'
    
  2. 添加模块依赖

    在你的应用模块的 build.gradle 文件中添加对 mylibrary 模块的依赖:

    dependencies {implementation project(':mylibrary')// 其他依赖项
    }
    
  3. 在你的模块中定义 Fragment

    mylibrary 模块中定义一个 CustomFragment

    // mylibrary/src/main/java/com/example/mylibrary/CustomFragment.kt
    package com.example.mylibraryimport android.os.Bundle
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import androidx.fragment.app.Fragmentclass CustomFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_custom, container, false)}
    }
    
    <!-- mylibrary/src/main/res/layout/fragment_custom.xml -->
    <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><!-- Fragment content goes here --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Custom Fragment" />
    </LinearLayout>
    
  4. 在主应用中使用 CustomFragment

    现在你可以在你的主应用中使用 mylibrary 模块中定义的 CustomFragment

    // MainActivity.kt
    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import androidx.fragment.app.Fragment
    import com.example.mylibrary.CustomFragmentclass MainActivity : AppCompatActivity() {private val fragmentMap = mutableMapOf<String, Fragment>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)if (savedInstanceState == null) {// 初始化 Fragment 实例并存储到 Map 中fragmentMap["ExampleFragment"] = ExampleFragment()fragmentMap["AnotherFragment"] = AnotherFragment()fragmentMap["CustomFragment"] = CustomFragment()// 默认加载的 FragmentswitchFragment("ExampleFragment")}}// 用于切换 Fragment 的方法fun switchFragment(tag: String) {val fragment = fragmentMap[tag]fragment?.let {supportFragmentManager.beginTransaction().replace(R.id.fragment_container, it, tag).addToBackStack(null).commit()}}
    }
    
  5. AnotherFragment 中调用 switchFragment 方法

    // AnotherFragment.kt
    class AnotherFragment : Fragment() {override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {// Inflate the layout for this fragmentreturn inflater.inflate(R.layout.fragment_another, container, false)}override fun onViewCreated(view: View, savedInstanceState: Bundle?) {super.onViewCreated(view, savedInstanceState)// 假设你有一个按钮来触发 Fragment 切换val button: Button = view.findViewById(R.id.switch_fragment_button)button.setOnClickListener {(activity as? MainActivity)?.switchFragment("CustomFragment")}}
    }
    

通过这种方式,你可以导入一个模块,并在主应用中使用该模块中定义的 Fragment。这使得代码更加模块化和可复用。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网络连接之队头阻塞!!!

一、什么是队头阻塞 队头阻塞&#xff0c;在网络模型中简单理解就是&#xff0c;对于队列型的请求模型&#xff0c;如HTTP的请求-响应模型、TCP的ACK确认机制&#xff0c;都依赖得到一个具体的响应包&#xff0c;如果收不到这个响应包&#xff0c;那下一个请求就不能发&#x…

如何高效安全的开展HPC数据传输,保护数据安全?

高性能计算&#xff08;HPC&#xff09;在多个行业和领域中都有广泛的应用&#xff0c;像科学研究机构、芯片IC设计企业、金融、生物制药、能源、航天航空等。HPC&#xff08;高性能计算&#xff09;环境中的数据传输是一个关键环节&#xff0c;它涉及到将数据快速、安全地在不…

hive的表操作

常用的hive命令 切换数据库use test;查询表的建表信息show create table 数据库名称.表名;查看表的类型信息desc formatted 数据库名称.表名; 删除内部表 drop table 数据库名称.表名; 先启动hdfs &#xff0c;mysql &#xff0c; hiveservice2&#xff0c;beeline CREATE [EX…

Jenkins 创建流水线任务

Jenkins是一个流行的持续集成&#xff08;Continuous Integration&#xff0c;CI&#xff09;工具。 Jenkins 创建任务 选择“流水线”类型&#xff0c;该类型的优点是定制化程度非常高 &#xff08;可选&#xff09;添加“参数化构建” 配置仓库选项(ssh连接、分支)和凭据…

vue 中使用element-ui实现锚点定位表单

效果图&#xff1a; 代码&#xff1a; html代码&#xff1a; <div class"content-left"><el-tabs :tab-position"left" tab-click"goAnchor"><el-tab-pane v-for"(item,index) in anchorNameList"v-anchor-scroll:ke…

《C++20设计模式》适配器模式经验分享

文章目录 一、前言二、对于接口的讨论三、实现1、对象适配器1.1 UML类图1.2 实现 2、类适配器 四、最后 一、前言 从适配器模式开始就是类的组合聚合&#xff0c;类与类之间结构性的问题了。 适配器模式解决的问题&#xff1a; 适配器模式能够在不破坏现有系统结构的情况下&a…

问题集锦1

01.inner中使用JwtTokenUtil.getUserCode() 前端调用上传&#xff08;java&#xff09;&#xff0c;上传使用加购 Overridepublic Boolean insertShoppingCart(InsertShoppingCartParamsDto dto) {// 通过userCode,itemCode和supplierCode来判断当前加购人添加到购物车的商品是…

前端FCP指标优化

优化前 第三方依赖按需引入之后&#xff0c;打包的总体积减小到初始值的55%&#xff0c;但是依然存在很大的js文件&#xff0c;需要继续优化 chunk-vendors.js进行分包之后 截图 compression-webpack-plugin压缩之后 截图

使用Nginx反向代理KKFileView遇到问题

使用KKFileView 4.0 以上版本 在KKFileView官网上&#xff0c;关于使用Nginx代理&#xff0c;建议配置如下 一、修改Nacos 在Nginx的conf文件夹中修改 nginx.conf ,新加 红框内的IP地址为代理服务器地址&#xff08;即安装KKFileView的服务器地址&#xff09; 二、修改KKFil…

【Dison夏令营 Day 07】用 Python 和 Rich 制作 Wordle克隆(下篇)

在大流行期间&#xff0c;Wordle 在 Twitter 上还算比较流行的一款基于网络的益智游戏&#xff0c;要求玩家每天在六次或更短时间内猜出一个新的五个字母的单词&#xff0c;每个人得到的单词都是一样的。 在本教程中&#xff0c;你将在终端上创建自己的 Wordle 克隆。自 2021 …

ViewBinding的使用(因为kotlin-android-extensions插件的淘汰)

书籍&#xff1a; 《第一行代码 Android》第三版 开发环境&#xff1a; Android Studio Jellyfish | 2023.3.1 问题&#xff1a; 3.2.4在Activity中使用Toast章节中使用到了kotlin-android-extensions插件,但是该插件已经淘汰,根据网上了解,目前使用了新的技术VewBinding替…

three.js地理坐标系有哪些,和屏幕坐标系的转换。

坐标系很好理解&#xff0c;就是点线面体的位置&#xff0c;一个点是一个坐标&#xff0c;一条线段2个坐标&#xff0c;一个矩形四个坐标&#xff0c;一个立方体8个坐标&#xff0c;three.js面对的是三维空间&#xff0c;屏幕则是二维的&#xff0c;这就面临着转换问题&#xf…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《面向电网调峰的电动汽车聚合商多层级实时控制策略》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

深入浅出:npm常用命令详解与实践【保姆级教程】

大家好&#xff0c;我是CodeQi&#xff01; 在我刚开始学习前端开发的时候&#xff0c;有一件事情让我特别头疼&#xff1a;管理和安装各种各样的依赖包。 那时候&#xff0c;我还不知道 npm 的存在&#xff0c;手动下载和管理这些库简直是噩梦。 后来&#xff0c;我终于接触…

Java + MySQL 实现存储完整 Json

Java MySQL 实现存储完整 Json 一、应用场景二、数据库配置三、后端代码配置1、实体类2、Service 实现类3、xml 文件 四、测试1、新增接口2、查询接口3、数据表内容 一、应用场景 将前端传过来的 Json 完整存储到 MySQL 中&#xff0c;涉及技术栈为 Java、MyBatis、MySQL。 …

风暴统计案例复现 | 先单后多的影响因素分析

今日要复现的是最最基础的影响因素分析文章&#xff0c;文章包括了①基本情况表、②卡方检验、③多因素logistic回归&#xff0c;复现过程将会详细截图讲解具体步骤&#xff0c;尤其是新手小白&#xff0c;请大家跟上脚步哦&#xff01; 本文为常见的先单后多影响因素分析的文章…

类型“{}”上不存在属性“xxxx”。ts(2339)

解决&#xff1a;类型“{}”上不存在属性“xxxx”和非类型化函数调用不能接受类型参数等问题。 问题发现 今天一个学生&#xff0c;发我一张图&#xff08;如下&#xff09;。 他从远端拉取到本地&#xff08;自家电脑&#xff09;后打开的代码视图&#xff0c;一大堆抛红。问…

Qualcomm QCA206x EasyMesh For Ubuntu

1. 引言 关于EasyMesh概念我们这里就不再过多的赘述&#xff0c;此篇文档的目的是&#xff0c;让广大初学者&#xff0c;有一个很方便的平台进行EasyMesh的学习和测试。 2. X86 Ubuntu平台 2.1 硬件环境准备 备注&#xff1a;QCA206x WiFi module推荐使用移远的FC64E/FC66E。…

我不小心把生产的数据改错了!同事帮我用MySQL的BinLog挽回了罚款

之前在生产做修改数据的时候不小心改错了一行数据&#xff0c;本来以为会被通报批评&#xff0c;但是同事利用binlog日志查看到了之前的旧数据&#xff0c;并且帮我回滚了&#xff0c;学到了&#xff0c;所以写了一篇binlog的文章分享给大家。 MySQL的Binary Log&#xff08;简…

查询 条件列值用notepad++批量添加单引号和逗号

参考&#xff1a;Notepad批量添加引号_notepad字符串统一加引号-CSDN博客 我需要批量修改数据表中某一列值指定的部分列&#xff0c;比如某个编号为CP0408242321001到CP0408242321101的条件。 我从数据表中把这个条件的所有编号复制出来了粘贴到了notepad里面。 如下图所示 从…