Android 在Kotlin中的片段内加载片段

Android 在Kotlin中的片段内加载片段,android,android-fragments,kotlin,fragment,Android,Android Fragments,Kotlin,Fragment,我心中有一个应用程序结构: 仪表板活动 家庭片段 ADS碎片 欢迎片段 经验碎片 考虑到这一点,我试图在HomeFragment中加载不同的片段,它也是一个片段 我在HomeFragment的onCreateView中编写了以下代码 fragment_greeting.xml 使用该if语句,我发现greetingFragment值返回null 我做错了什么?主页片段应该包含三个用于加载AdsFragment、问候语片段和体验片段的框架布局。 可以使用子片段管理器将片段加载到框架布局。主片段应包

我心中有一个应用程序结构:

仪表板活动

家庭片段 ADS碎片 欢迎片段 经验碎片 考虑到这一点,我试图在HomeFragment中加载不同的片段,它也是一个片段

我在HomeFragment的onCreateView中编写了以下代码

fragment_greeting.xml

使用该if语句,我发现greetingFragment值返回null


我做错了什么?

主页片段应该包含三个用于加载AdsFragment、问候语片段和体验片段的框架布局。
可以使用子片段管理器将片段加载到框架布局。

主片段应包含三个用于加载AdsFragment、问候语片段和体验片段的框架布局。 可以使用子片段管理器将片段加载到框架布局。

在您的HomeFragment中尝试此操作

并调用不带findFragmentbyId的片段,如下所示:

 val fm = context.supportFragmentManager
            val fragmentTransaction: FragmentTransaction
            val fragment = GreetingFragment()
            fragmentTransaction = fm.beginTransaction()
            fragmentTransaction.replace(R.id.container, fragment)
                .addToBackStack(null)
            fragmentTransaction.commit()
在你的家里试试这个

并调用不带findFragmentbyId的片段,如下所示:

 val fm = context.supportFragmentManager
            val fragmentTransaction: FragmentTransaction
            val fragment = GreetingFragment()
            fragmentTransaction = fm.beginTransaction()
            fragmentTransaction.replace(R.id.container, fragment)
                .addToBackStack(null)
            fragmentTransaction.commit()

有多种方法可以实例化片段。您正在使用的方法除了声明布局之外什么都不做,这不是您想要的!请使用以下方法正确执行此操作

<LinearLayout>
 <fragment android:id="@+id/ad" android:name="._fragments.dash.AdFragment" />
<fragment android:id="@+id/greeting" android:name="._fragments.dash.GreetingFragment"/>
<fragment android:id="@+id/experience" android:name="._fragments.dash.ExpFragment"/>
</LinearLayout>
在这里,android:name中指定的类是指扩展Fragment类的专用fragments类。您需要在专用布局资源中指定每个片段的布局,例如R.layout.ad_片段、R.layout.greeting_片段和R.layout.exp_片段,这些片段必须在每个类的onCreateView函数中膨胀


有关更多信息,请参阅。

实例化片段有多种方法。您正在使用的方法除了声明布局之外什么都不做,这不是您想要的!请使用以下方法正确执行此操作

<LinearLayout>
 <fragment android:id="@+id/ad" android:name="._fragments.dash.AdFragment" />
<fragment android:id="@+id/greeting" android:name="._fragments.dash.GreetingFragment"/>
<fragment android:id="@+id/experience" android:name="._fragments.dash.ExpFragment"/>
</LinearLayout>
在这里,android:name中指定的类是指扩展Fragment类的专用fragments类。您需要在专用布局资源中指定每个片段的布局,例如R.layout.ad_片段、R.layout.greeting_片段和R.layout.exp_片段,这些片段必须在每个类的onCreateView函数中膨胀


请参阅以获取更多信息。

要在同一视图中加载不同的片段,我这样做了

    private val manager = supportFragmentManager
当您必须加载每个片段时,不要认为您必须同时显示所有片段,您可以这样做

    val transaction = manager.beginTransaction()
    val fragment = FragmentOne()
    transaction.replace(R.id.fragment_holder, fragment)
    transaction.addToBackStack(null)
    transaction.commit()
好的做法是,在听不同的按钮tapu,然后安装不同的片段时,有一个通用的方法,因为制作不同的按钮会产生更多的复制代码

 override fun onOptionsItemSelected(item: MenuItem): Boolean {

    val fragment = when(item.itemId) {
        R.id.ads_menu -> FragmentAds()
        R.id.grets_menu -> FragmentGreeting()
        R.id.exp_menu -> FragmentExperience()
        else ->  return super.onOptionsItemSelected(item)
    }

    val transaction= manager.beginTransaction()
    transaction.replace(R.id.fragment_holder, fragment)
    transaction.addToBackStack(null)
    transaction.commit()
    return true
}
当然,有三个片段类具有它们的布局并覆盖所有方法。 我在profiler中也尝试过这个,似乎是这样

如果我们可以这样调用这个解决方案,那么问题是,在back-pressed上,所有片段的历史都被加载,因为replace-remove并添加一个新的片段

为了避免这种情况,所有的片段都可能是可见的,更改按钮只需更改所选的片段,但这当然会使when语句复杂化

ft = fm.beginTransaction();
ft.hide(getFragmentManager().findFragmentByTag("searchFragment"));
ft.add(R.id.main_fragment, yourDetailfragment);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();

为了在同一视图中加载不同的片段,我这样做了

    private val manager = supportFragmentManager
当您必须加载每个片段时,不要认为您必须同时显示所有片段,您可以这样做

    val transaction = manager.beginTransaction()
    val fragment = FragmentOne()
    transaction.replace(R.id.fragment_holder, fragment)
    transaction.addToBackStack(null)
    transaction.commit()
好的做法是,在听不同的按钮tapu,然后安装不同的片段时,有一个通用的方法,因为制作不同的按钮会产生更多的复制代码

 override fun onOptionsItemSelected(item: MenuItem): Boolean {

    val fragment = when(item.itemId) {
        R.id.ads_menu -> FragmentAds()
        R.id.grets_menu -> FragmentGreeting()
        R.id.exp_menu -> FragmentExperience()
        else ->  return super.onOptionsItemSelected(item)
    }

    val transaction= manager.beginTransaction()
    transaction.replace(R.id.fragment_holder, fragment)
    transaction.addToBackStack(null)
    transaction.commit()
    return true
}
当然,有三个片段类具有它们的布局并覆盖所有方法。 我在profiler中也尝试过这个,似乎是这样

如果我们可以这样调用这个解决方案,那么问题是,在back-pressed上,所有片段的历史都被加载,因为replace-remove并添加一个新的片段

为了避免这种情况,所有的片段都可能是可见的,更改按钮只需更改所选的片段,但这当然会使when语句复杂化

ft = fm.beginTransaction();
ft.hide(getFragmentManager().findFragmentByTag("searchFragment"));
ft.add(R.id.main_fragment, yourDetailfragment);
ft.addToBackStack(null);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
ft.commit();

尝试使用android:name在@RahulShukla中指定不起作用的片段类。抱歉:/抱歉,我也错过了。老实说,你不是在找ViewPager+FragmentPagerAdapter吗?哦,我已经记下了那个组合。只是,我想要一些地方,其中的片段是静态的,并且是通过编程加载的。请尝试使用android:name在@RahulShukla中指定不起作用的片段类。抱歉:/抱歉,我也错过了。老实说,你不是在找ViewPager+FragmentPagerAdapter吗?哦,我已经记下了那个组合。只是,我想要一些地方,其中的片段是静态的,并且是通过编程加载的。不需要lateinit变量,片段已经有了getActivity方法。@EpicPandaForce是的,我们可以使用该方法,但我有时会遇到崩溃,所以我认为这是安全的方法。不需要lateinit变量,片段已经有了一个getActivity方法。@EpicPandaForce是的,我们可以使用这个方法,但我有时会遇到崩溃,所以我认为这是安全的方法。