【问题标题】:How to change Fragment Kotlin如何更改片段 Kotlin
【发布时间】:2019-02-18 10:53:22
【问题描述】:

我从科特林开始,不知道如何在片段之间切换,我试过这段代码:

val manager = supportFragmentManager
    val transaction = manager.beginTransaction()
    transaction.add(R.layout.fragment_information.toInt(), ComplainFragment())
    transaction.commit()

R.layout.fragment_information.toInt()

但是我这个参数有一个错误,因为它没有找到片段 ID。

【问题讨论】:

标签: android android-fragments kotlin fragment


【解决方案1】:

我通常使用替换来在片段之间进行更改。也只将 R.layout.fragment_information 更改为 R.id.fragment_layout_id,所以不需要 toInt()

transaction.replace(R.id.fragment_layout_id, fragment)

这是我的建议。

    var fragment: Fragment? = null

            when (itemId) {
                        R.id.fragment_information -> {
                            fragment = ComplainFragment()
                        }
            }

            if (fragment != null) {
                    val transaction = supportFragmentManager.beginTransaction()
                    transaction.replace(R.id.fragment_layout_id, fragment)
                    transaction.commit()
            }

【讨论】:

    【解决方案2】:

    这是一个示例,您可以通过单击另一个片段中的按钮来转到片段或活动:

    class Fragment_One: Fragment() {
    
        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_one, container, false)
        }
    
        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            super.onViewCreated(view, savedInstanceState)
    
            btn_goToActivity2.setOnClickListener {
                val intent = Intent(context, SecondActivity::class.java)
                startActivity(intent)
            }
    
            btn_goToFragment2.setOnClickListener {
                var fr = getFragmentManager()?.beginTransaction()
                fr?.replace(R.id.fragment, Fragment_Two())
                fr?.commit()
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      其他答案会起作用,但我们仍然可以通过在 Kotlin 中使用扩展函数来改进很多。

      向 FragmentManager 类添加扩展函数,如下所示,

      inline fun FragmentManager.doTransaction(func: FragmentTransaction.() -> 
      FragmentTransaction) {
          beginTransaction().func().commit()
      }
      

      然后为 AppCompatActivity 类创建一个扩展函数,

      fun AppCompatActivity.addFragment(frameId: Int, fragment: Fragment){
          supportFragmentManager.doTransaction { add(frameId, fragment) }
      }
      
      
      fun AppCompatActivity.replaceFragment(frameId: Int, fragment: Fragment) {
          supportFragmentManager.doTransaction{replace(frameId, fragment)}
      }
      
      fun AppCompatActivity.removeFragment(fragment: Fragment) {
          supportFragmentManager.doTransaction{remove(fragment)}
      }
      

      现在,要从任何活动中添加和删除片段,您只需像这样调用,

      addFragment(R.id.fragment_container, fragment)
      
      replaceFragment(R.id.fragment_container, fragment)
      

      请参考以下链接了解更多信息,

      https://medium.com/thoughts-overflow/how-to-add-a-fragment-in-kotlin-way-73203c5a450b

      【讨论】:

      • 这是最好的答案,但我很好奇如果它是只读的,我如何将此函数添加到 fragmentManager 类。我在 mainActivity 中玩得很开心,但如何在 kotlin 中调用它?
      【解决方案4】:

      添加片段时,需要将其添加到 Activity 布局中存在的 ID,而不是整个布局:

      supportFragmentManager.beginTransaction().add(R.id.some_id_in_your_activity_layout, ComplainFragment()).commit()
      

      【讨论】:

        【解决方案5】:

        如果有人仍然需要快速解决此问题。我创建了一个可以在您需要更改片段时轻松调用的函数。

         private fun replaceFragment(fragment: Fragment) {
            val transaction = supportFragmentManager.beginTransaction()
            transaction.replace(R.id.frame, fragment)
            transaction.commit()
        }
        

        R.id.frame 在这种情况下是我的 Framelayout 在将保存我的片段的活动中的 id。您现在所要做的就是调用该函数。

        replaceFragment(HomeFragment())
        

        【讨论】:

          【解决方案6】:

          fragment-ktxjetpack 库包含方便的扩展功能,可以简化很多事情,including transactions:

          // MyActivity.kt
          
          class MyActivity : AppCompatActivity() {
            ...
          
            fun showMyFragment() {
              val fragment = MyFragment()
              supportFragmentManager.commit {
                replace(R.id.fragment_container, fragment)
              }
            }
          }
          

          R.id.fragment_container 它是父布局中片段容器的 id。有FragmentContainerViewrecommended 容器,例如:

          <!-- my_activity_layout.xml -->
          
          <?xml version="1.0" encoding="utf-8"?>
          <androidx.constraintlayout.widget.ConstraintLayout ...>
          
              <androidx.fragment.app.FragmentContainerView
                  android:id="@+id/fragment_container"
                  ... />
          
              ...
          
          </androidx.constraintlayout.widget.ConstraintLayout>
          

          但如果您的目的是实现应用内导航,则使用Navigation component 而不是手动切换片段会更好也更容易。

          【讨论】:

            【解决方案7】:

            这是我在 kotlin 中将当前片​​段更改为 orther 的解决方案:

            val supportFragment = SupportFragment()
            requireActivity().supportFragmentManager.beginTransaction()
                             .add(this.id, supportFragment)
                             .addToBackStack("ok")
                             .commit()
            

            【讨论】:

              【解决方案8】:
              private fun transitionFragment(fragment: Fragment) {
                  val transition = requireActivity().supportFragmentManager.beginTransaction()
                  transition.replace(R.id.fragment_container_create_void_parent, fragment)
                            .addToBackStack(null).commit()
              }
              

              【讨论】:

              • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
              猜你喜欢
              • 2018-11-11
              • 2021-10-16
              • 2020-01-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-03-23
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多