使用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

**1. Java**实现

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

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

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

    java 复制代码
    // ExampleFragment.java
    public class ExampleFragment extends Fragment {
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_example, container, false);
        }
    }
    xml 复制代码
    <!-- fragment_example.xml -->
    <LinearLayout
        xmlns: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 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Example Fragment" />
    </LinearLayout>
  3. 在主 Activity 中管理 Fragments :在你的主 Activity 中使用 FragmentManager 来替换占位符中的 Fragment

    java 复制代码
    // MainActivity.java
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // 默认加载的 Fragment
            if (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

    java 复制代码
    // 切换到另一个 Fragment
    switchFragment(new AnotherFragment());

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

2.kotlin实现

2.1 添加基础切换流程

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

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

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

    kotlin 复制代码
    // ExampleFragment.kt
    class ExampleFragment : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_example, container, false)
        }
    }
    xml 复制代码
    <!-- fragment_example.xml -->
    <LinearLayout
        xmlns: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 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Example Fragment" />
    </LinearLayout>
  3. 在主 Activity 中管理 Fragments :在你的主 Activity 中使用 FragmentManager 来替换占位符中的 Fragment

    kotlin 复制代码
    // MainActivity.kt
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            // 默认加载的 Fragment
            if (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

    kotlin 复制代码
    // 切换到另一个 Fragment
    switchFragment(AnotherFragment())

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

2.2 页面中获取主界面

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

下面是一个示例:

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

    kotlin 复制代码
    // AnotherFragment.kt
    class AnotherFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return 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())
            }
        }
    }
    xml 复制代码
    <!-- fragment_another.xml -->
    <LinearLayout
        xmlns: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 -->
        <Button
            android: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 可以被调用。

    kotlin 复制代码
    // MainActivity.kt
    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            // 默认加载的 Fragment
            if (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 实例

    kotlin 复制代码
    // MainActivity.kt
    class MainActivity : AppCompatActivity() {
        private lateinit var exampleFragment: ExampleFragment
        private lateinit var anotherFragment: AnotherFragment
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            if (savedInstanceState == null) {
                // 初始化 Fragment 实例
                exampleFragment = ExampleFragment()
                anotherFragment = AnotherFragment()
                
                // 默认加载的 Fragment
                supportFragmentManager.beginTransaction()
                    .replace(R.id.fragment_container, exampleFragment)
                    .commit()
            } else {
                // 恢复已存在的 Fragment 实例
                exampleFragment = supportFragmentManager.findFragmentByTag("ExampleFragment") as ExampleFragment
                anotherFragment = 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 方法

    kotlin 复制代码
    // AnotherFragment.kt
    class AnotherFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return 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 实例

    kotlin 复制代码
    // 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()
    
                // 默认加载的 Fragment
                switchFragment("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 方法

    kotlin 复制代码
    // AnotherFragment.kt
    class AnotherFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return 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

    kotlin 复制代码
    // ExampleFragment.kt
    class ExampleFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return 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 文件中包含了该模块:

    gradle 复制代码
    include ':app', ':mylibrary'
  2. 添加模块依赖

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

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

    mylibrary 模块中定义一个 CustomFragment

    kotlin 复制代码
    // mylibrary/src/main/java/com/example/mylibrary/CustomFragment.kt
    package com.example.mylibrary
    
    import android.os.Bundle
    import android.view.LayoutInflater
    import android.view.View
    import android.view.ViewGroup
    import androidx.fragment.app.Fragment
    
    class CustomFragment : Fragment() {
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_custom, container, false)
        }
    }
    xml 复制代码
    <!-- mylibrary/src/main/res/layout/fragment_custom.xml -->
    <LinearLayout
        xmlns: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 -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Custom Fragment" />
    </LinearLayout>
  4. 在主应用中使用 CustomFragment

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

    kotlin 复制代码
    // MainActivity.kt
    import android.os.Bundle
    import androidx.appcompat.app.AppCompatActivity
    import androidx.fragment.app.Fragment
    import com.example.mylibrary.CustomFragment
    
    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()
                fragmentMap["CustomFragment"] = CustomFragment()
    
                // 默认加载的 Fragment
                switchFragment("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 方法

    kotlin 复制代码
    // AnotherFragment.kt
    class AnotherFragment : Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return 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。这使得代码更加模块化和可复用。

相关推荐
暮志未晚Webgl21 分钟前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5
麦田里的守望者江42 分钟前
KMP 中的 expect 和 actual 声明
android·ios·kotlin
Dnelic-1 小时前
解决 Android 单元测试 No tests found for given includes:
android·junit·单元测试·问题记录·自学笔记
佛系小嘟嘟1 小时前
Android Studio不显示需要的tag日志解决办法《All logs entries are hidden by the filter》
android·ide·android studio
mariokkm2 小时前
Django一分钟:django中收集关联对象关联数据的方法
android·django·sqlite
长亭外的少年2 小时前
如何查看 Android 项目的依赖结构树
android
深海呐4 小时前
Android 从本地选择视频,用APP播放或进行其他处理
android·音视频·从本地选择视频,用app播放·从本地选择视频,并拿到信息·跳转到本地视频列表
深海呐4 小时前
Android Google登录接入
android·google登录接入·android 谷歌登录接入·google登录·android google
daiyang123...4 小时前
MySQL【知识改变命运】11
android·数据库·mysql
8931519605 小时前
Android开发教程案例源码分享-匹配动画多个头像飘动效果
android·android开发·android教程·kotlin教程·android头像飘动动画·android匹配动画·android多个头像飘动动画