• Fragment碎片的切换


        在上一篇[“Android常见的高级组件搭建移动应用界面”](https://editor.csdn.net/md/?articleId=127545452)中,是通过导航来实现信息栏的显示。这样的操作过于简单。在实际上,通过侧滑菜单的导航菜单和底部视图导航BottomNavigationView的导航往往可以用于不同Fragment切换来完成。
        通过Fragment定义不同的UI界面,结合导航实现不同界面的切换,让交互更好友好和方便。
    
    • 1
    • 2

    一、定义三个不同界面的Fragment
    第一个碎片类定义代码如下:

     object FirstFragment : Fragment() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
        }
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_first, container, false)
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第二个碎片类定义代码如下:

    object SecondFragment : Fragment() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
        }
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_second, container, false)
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    第三个碎片类定义代码如下:

    object ThirdFragment : Fragment() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
        }
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_third, container, false)
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    上述代码中均将三个碎片类定义成对象类,对象类通过类来维护唯一的对象即自己本身。
    二、修改上一篇"Android常见的高级组件搭建移动应用界面"的MainActivity对应的布局文件activity_main.xml,使用FragmentContainerView来承载碎片。代码如下:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.drawerlayout.widget.DrawerLayout
        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:id="@+id/drawerLayout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@android:color/holo_orange_dark"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintVertical_bias="0.0" />
    
            **<androidx.fragment.app.FragmentContainerView
                android:id="@+id/fragmentLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="1.0"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/toolbar"
                app:layout_constraintVertical_bias="0.0"
                />**
    
         <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottomNavigationView"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/purple_200"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintHorizontal_bias="0.5"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toBottomOf="@+id/toolbar"
                app:layout_constraintVertical_bias="1.0"
                app:menu="@menu/menu_navigation"
                />
        </androidx.constraintlayout.widget.ConstraintLayout>
    
        <com.google.android.material.navigation.NavigationView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/navigationView"
            android:layout_gravity="start"
            app:menu="@menu/menu_navigation"
            app:headerLayout="@layout/layout_header"/>
    </androidx.drawerlayout.widget.DrawerLayout>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59

    三、在主活动MainActivity中增加碎片处理的方式
    碎片处理有两种方案:
    (1)碎片替换
    在界面中不同的碎片进行替换,如果需要切换一个新的碎片界面,就用一个新的碎片对象替换原来的碎片。这时代码可以调整为:

    class MainActivity : AppCompatActivity() {
        lateinit var binding:ActivityMainBinding
       
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            replaceFragment(FirstFragment)
    
            configToolbar()
            configDrawerLayout()
            configBottomNavigationView()
           
            setContentView(binding.root)
        }
    ......
        /**
         * Config toolbar
         * 设置头部
         */
        fun configToolbar(){
            setSupportActionBar(binding.toolbar)
        }
    
        fun configDrawerLayout(){
            supportActionBar?.let{
                it.setDisplayHomeAsUpEnabled(true)
                it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
            }
            binding.navigationView.setCheckedItem(R.id.aboutItem)
            binding.navigationView.itemIconTintList = null
            binding.navigationView.setNavigationItemSelectedListener {
                when(it.itemId){
                    R.id.appItem->replaceFragment(FirstFragment)
                    R.id.favorityItem->replaceFragment(SecondFragment)
                    R.id.configItem->repalceFragment(ThirdFragment)
                }
                binding.drawerLayout.closeDrawer(GravityCompat.START)
                true
            }
        }
    
        fun configBottomNavigationView(){
            binding.bottomNavigationView.itemIconTintList = null
            binding.bottomNavigationView.setOnItemSelectedListener{
                when(it.itemId){
                    R.id.appItem->replaceFragment(FirstFragment)
                    R.id.favorityItem->replaceFragment(SecondFragment)
                    R.id.configItem->repalceFragment(ThirdFragment)
                }
                true
            }
        }
    
    
        /**
         * 实现碎片的替换
         * @param fragment Fragment
         */
        fun replaceFragment(fragment:Fragment){
            val transaction = supportFragmentManager.beginTransaction()
            transaction.replace(R.id.fragmentLayout,fragment)
            transaction.addToBackStack(null)
            transaction.commit()
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    (2)碎片的隐藏和显示
    将所有碎片加入到事务Transaction中,通过事务的显示或隐藏碎片来达到切换碎片对应界面的目的。这时代码可以调整成:

    class MainActivity : AppCompatActivity() {
        lateinit var binding:ActivityMainBinding
        lateinit var currentFragment:Fragment
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = ActivityMainBinding.inflate(layoutInflater)
            currentFragment = FirstFragment
            
            configToolbar()
            configDrawerLayout()
            configBottomNavigationView()
            switchFragment(currentFragment)
            setContentView(binding.root)
        }
    ......
        /**
         * Config toolbar
         * 设置头部
         */
        fun configToolbar(){
            setSupportActionBar(binding.toolbar)
        }
    
        fun configDrawerLayout(){
            supportActionBar?.let{
                it.setDisplayHomeAsUpEnabled(true)
                it.setHomeAsUpIndicator(R.mipmap.ic_launcher)
            }
            binding.navigationView.setCheckedItem(R.id.aboutItem)
            binding.navigationView.itemIconTintList = null
            binding.navigationView.setNavigationItemSelectedListener {
                **when(it.itemId){
                    R.id.appItem->switchFragment(FirstFragment)
                    R.id.favorityItem->switchFragment(SecondFragment)
                    R.id.configItem->switchFragment(ThirdFragment)
                }**
                binding.drawerLayout.closeDrawer(GravityCompat.START)
                true
            }
        }
    
        fun configBottomNavigationView(){
            binding.bottomNavigationView.itemIconTintList = null
            binding.bottomNavigationView.setOnItemSelectedListener{
                **when(it.itemId){
                    R.id.appItem->switchFragment(FirstFragment)
                    R.id.favorityItem->switchFragment(SecondFragment)
                    R.id.configItem->switchFragment(ThirdFragment)
                }**
                true
            }
        }
    
        ......
        /**
         * 实现碎片的切换
         * @param fragment Fragment
         */
        **fun switchFragment(fragment: Fragment){
            val transaction = supportFragmentManager.beginTransaction()
            if(!fragment.isAdded){
                transaction.hide(currentFragment)
                transaction.add(R.id.fragmentLayout,fragment)
            }else{
                transaction.hide(currentFragment)
                transaction.show(fragment)
            }
            currentFragment = fragment
            transaction.commit()
        }**
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    参考文献:
    《Android移动应用开发(微课版)》 陈轶 清华大学出版社 
     ISBN:978-7-302-59734-6

  • 相关阅读:
    节奏达人疯狂猜歌双端流量主小程序开发
    Execution failed for task ‘:app:javaPreCompileDebug‘.
    spring源码 - AOP原理理解
    20.Redis系列之高可用集群模式
    码蹄集 - MT2094 - 回文之时:第4组数据错误
    ASP.NET MVC-制作可排序的表格组件-PagedList版
    计算机网络(自顶向下方法)-传输层
    AI基础设施Grass零撸空投,最新融资350万美元!
    算法设计与分析期末复习题
    Docker Hub 镜像代理加速
  • 原文地址:https://blog.csdn.net/userhu2012/article/details/127549993