简体   繁体   English

在 kotlin 中打开另一个片段

[英]Open fragment from another one in kotlin

I'm totally desesperate.我完全绝望了。 I try to open/replace fragment from one to another and only docs I can find is from an Activity or only in Java (with the getFragmentManager() method, seems to not exist in Kotlin).我尝试从一个片段到另一个片段打开/替换,只有我能找到的文档来自 Activity 或仅在 Java 中(使用 getFragmentManager() 方法,在 Kotlin 中似乎不存在)。

supportFragmentManager is only available inside an Activity, and I'm using a fragment and adapter. supportFragmentManager 仅在 Activity 内可用,我使用的是片段和适配器。

Could you please help me?请你帮助我好吗?

I think it's unless to show my code because it's just give nothing, only errors我认为除非显示我的代码,因为它什么都不提供,只有错误

None of the answers worked for me.没有一个答案对我有用。 I tried something else and create an interface :我尝试了其他方法并创建了一个界面:

interface AdapterCallbackAlbum {
fun onClickItem(album: Album)}

And implement this in my first fragment并在我的第一个片段中实现它

class ListAlbumsFragment : Fragment(), AdapterCallbackAlbum {
  override fun onClickItem(album: Album) {
  val fragment = ListTracksFragment.newInstance()
  val transaction = childFragmentManager.beginTransaction()
  transaction.replace(R.id.album_fragment, fragment)
  transaction.commit()
}

And finally the adapter:最后是适配器:

    class AlbumAdapter(val context: Context, private val 
    adapterCallbackAlbum: AdapterCallbackAlbum): Adapter<ViewHolder>() {
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, 
    position: Int) {
        val album = albumList[position]
        holder.itemView.setOnClickListener { 
          adapterCallbackAlbum.onClickItem(album)
       }}

But the only result I get is the second fragment put on the first one even if I call a :但我得到的唯一结果是第二个片段放在第一个片段上,即使我调用 a :

transaction.remove(ListAlbumFragment.newInstance())

A friend of mine finally solved my problem (maybe it could help someone).我的一个朋友终于解决了我的问题(也许它可以帮助某人)。

 override fun onClickItem(album: Album) {
    val fragment = ListTracksFragment.newInstance()
    val transaction = fragmentManager.beginTransaction()
    transaction.replace(R.id.content, fragment)
    transaction.addToBackStack(null)
    transaction.commit()
}

The trouble was we start from MainActivity, which load a fragment, inside this fragment, we have to load another one on a click event.问题是我们从 MainActivity 开始,它加载一个片段,在这个片段中,我们必须在点击事件上加载另一个片段。 So the fragment to replace is not the current fragment, but the content of main_activity.xml.所以要替换的fragment不是当前fragment,而是main_activity.xml的内容。

Thank's to all for your quick answers感谢大家的快速回答

It is simple as it is in activity just do it like this.这很简单,因为它在活动中就这样做。

 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    childFragmentManager.beginTransaction().replace(R.id.action_container,ChildFragment.getInstance()).commit()
}

Use below function inorder to add or replace any fragment使用下面的函数来添加或替换任何片段

fun addFragment(
fm: FragmentManager,
fragment: Fragment,
container: Int,
replace: Boolean,
addToBackStack: Boolean,
addAnimation: Boolean
) {
val fragmentTransaction = fm.beginTransaction()
if (addAnimation)
    fragmentTransaction.setCustomAnimations(
        R.animator.slide_in_rght,
        R.animator.slide_out_left,
        R.animator.slide_in_left,
        R.animator.slide_out_rght
    )
if (replace)
    fragmentTransaction.replace(container, fragment, fragment.javaClass.name)
else
    fragmentTransaction.add(container, fragment, fragment.javaClass.name)
if (addToBackStack)
    fragmentTransaction.addToBackStack(fragment.javaClass.name)
 fragmentTransaction.commit()
}

In your fragment class where you want to open another fragment , you can call the above function :在你想要打开另一个片段的片段类中,你可以调用上面的函数:

fragmentManager?.let {
                        addFragment(
                            it, ABCFragment(), android.R.id.content, false,  true,
                            true
                        )
                    }

or或者

addFragment(
                        activity?.supportFragmentManager
                        , SignupFinalStepFragment.newInstance(
                            phoneNumber = phoneNumber?:"",
                            emailAddress = emailAddress ?: ""
                        ), android.R.id.content, false, addToBackStack = true,
                        addAnimation = true
                    )

Both the method calls are same , the only difference is activity?.supportFragmentManager which should be non null .两个方法调用是相同的,唯一的区别是 activity?.supportFragmentManager 应该是非 null 。

If you are using a Fragment, you can get the context of the activity and retrieve the fragment manager from it.如果您使用的是 Fragment,则可以获取 Activity 的上下文并从中检索 Fragment 管理器。 So, inside your fragment class do this因此,在您的片段类中执行此操作

FragmentManager fm = ((Activity) getContext).getSupportFragmentManager();

Not that you have your fragment manager, you only need the id of the container that you want to add/replace your other fragment and you are good to go.并不是说您有片段管理器,您只需要要添加/替换其他片段的容器的 ID,就可以了。

fm.beginTransaction().add(R.layout.container_id, OtherFragmentObject()).commit();

In your CurrentFragment, override the onActivityCreated like so:在您的 CurrentFragment 中,像这样覆盖 onActivityCreated:

override fun onActivityCreated(savedInstanceState: Bundle?) {
    super.onActivityCreated(savedInstanceState)

    yourOwnButton.setOnClickListener{

        requireActivity().supportFragmentManager.beginTransaction()
            .replace(R.id.your_fragment_container, AnotherFragment.newInstance())
            .commit()
    }
}

and inside your AnotherFragment you should have a companion object like so:在您的 AnotherFragment 中,您应该有一个像这样的伴生对象:

companion object {
    fun newInstance() = StudentFragment()
}
   //try it 
    fun commitFragmenttoFragment(fragmentManager: FragmentManager, fragment: Fragment, tag: String) {
            val fragmentTransaction = fragmentManager.beginTransaction()
            fragmentTransaction.replace(R.`enter code here`id.fragment_main, fragment)
            fragmentTransaction.addToBackStack(null)
            fragmentTransaction.commit()
        }

    //in this fragment us activity!!.supportFragmentManager

    commitFragmenttoFragment(activity!!.supportFragmentManager,AddManageValue(), AddManageValue().TAG)

if anyone care, I changed second fragment to a FrameLayout after I put this code on my fragment如果有人关心,我将这段代码放在我的片段上后,将第二个片段更改为FrameLayout

 childFragmentManager.beginTransaction()
            .replace(R.id.mFragment,secondFragment())
            .commit()

Here is how you can navigate from one fragment to another in kotlin :以下是在 kotlin 中从一个片段导航到另一个片段的方法:

<fragment
        android:id="@+id/titleFragment"
        android:name="com.dheeraj.guessbro.title.TitleFragment"
        android:label="title_fragment"
        tools:layout="@layout/title_fragment">
       <action
            android:id="@+id/action_titleFragment_to_gameFragment"
            app:destination="@id/gameFragment" />
    </fragment>

and then go to the TitleFragment.kt file and just use this code :然后转到 TitleFragment.kt 文件并使用以下代码:

binding.btn_open.setOnClickListener { findNavController(this).navigate(R.id.action_titleFragment_to_gameFragment) } binding.btn_open.setOnClickListener { findNavController(this).navigate(R.id.action_titleFragment_to_gameFragment) }

If you are not using view binding then you can first define the variable using findViewById and then use the clickListener.如果您不使用视图绑定,那么您可以先使用 findViewById 定义变量,然后使用 clickListener。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM