添加/替换片段的任何代码改进

时间:2017-08-16 12:37:25

标签: android android-fragments kotlin

我已经开始学习Kotlin并且不知道该语言的所有功能。

该函数用于显示FrameLayout中的片段。逻辑是第一次它始终add()片段,下次它将replace()。此外,在某些情况下,我需要使用addToBackStack()并在相同的情况下禁用左侧菜单。

fun showFragment(fragment : Fragment,
                 isReplace: Boolean = true,
                 backStackTag: String? = null,
                 isEnabled: Boolean = true)
{
    /* Defining fragment transaction */
    val fragmentTransaction = supportFragmentManager
            .beginTransaction()

    /* Select if to replace or add a fragment */
    if(isReplace)
        fragmentTransaction.replace(R.id.frameLayoutContent, fragment, backStackTag)
    else
        fragmentTransaction.add(R.id.frameLayoutContent, fragment)

    /* Select if to add to back stack */
    if(backStackTag != null)
        fragmentTransaction.addToBackStack(fragment.javaClass.name)

    fragmentTransaction.commit()
    enableDrawer(isEnabled)
}

问题:对于与Kotlin语言规范相关的功能代码是否有一些可能的改进,以使代码更清晰,因为现在该功能看起来像一个质量。

4 个答案:

答案 0 :(得分:15)

我发布了一个关于以下答案的blog

我会向FragmentManager写一个Extension function,它接受​​一个Lambda with Receiver作为参数。

inline fun FragmentManager.inTransaction(func: FragmentTransaction.() -> Unit) {
    val fragmentTransaction = beginTransaction()
    fragmentTransaction.func()
    fragmentTransaction.commit()
}

要添加fragment,我们可以从Activity现在这样调用:

supportFragmentManager.inTransaction {
    add(R.id.frameLayoutContent, fragment)
}

这样做的好处是,我们现在每次添加或替换beginTransaction()时都不必致电commit()Fragment。你浪费了几个小时来调试只是为了发现你错过了在Java中调用commit()

接下来,我会将Extension functions写入AppCompatActivity

fun AppCompatActivity.addFragment(fragment: Fragment, frameId: Int, backStackTag: String? = null) {
    supportFragmentManager.inTransaction {
        add(frameId, fragment)
        backStackTag?.let { addToBackStack(fragment.javaClass.name) }
    }
}

fun AppCompatActivity.replaceFragment(fragment: Fragment, frameId: Int, backStackTag: String? = null) {
    supportFragmentManager.inTransaction {
        replace(frameId, fragment)
        backStackTag?.let { addToBackStack(fragment.javaClass.name) }
    }
}

现在我们可以在一行中添加/替换任何Fragment中的Activity,而无需任何其他限定符:

addFragment(yourFragment, R.id.frameLayoutContent, "tag")

replaceFragment(yourFragment, R.id.frameLayoutContent, "tag")

答案 1 :(得分:5)

我喜欢使用withlet,因为我有一些与使用大量变量相关的代码和null checks

所以我做这样的事情:

fun showFragment(fragment : Fragment,
                 isReplace: Boolean = true,
                 backStackTag: String? = null,
                 isEnabled: Boolean = true)
{
    /* Defining fragment transaction */
    with(supportFragmentManager.beginTransaction()) {

        /* Select if to replace or add a fragment */
        if(isReplace)
            replace(R.id.frameLayoutContent, fragment, backStackTag)
        else
            add(R.id.frameLayoutContent, fragment)

        /* Select if to add to back stack */
        backStackTag?.let { addToBackStack(it) }

        commit()
    }
    enableDrawer(isEnabled)
}

答案 2 :(得分:0)

一切都很好。可能在这里

if(backStackTag != null)
    fragmentTransaction.addToBackStack(fragment.javaClass.name)

您希望使用backStackTag这样添加片段

if(backStackTag != null)
    fragmentTransaction.addToBackStack(backStackTag)

答案 3 :(得分:0)

您可以创建如下扩展功能:

  1. 导入android.support.v4.app.FragmentManagerandroid.support.v4.app.FragmentTransaction,如果您希望使用supportFragmentManager(使用支持库)使您的应用与运行Android 1.6以下版本的设备兼容,的fragmentManager

  2. 在顶层(即直接在软件包下方)定义以下功能:

    inline fun FragmentManager.inTransaction(func: FragmentTransaction.() Unit) {
        val fragmentTransaction = beginTransaction()
        fragmentTransaction.func()
        fragmentTransaction.commit() 
    }
    
  3. 从任何活动中调用函数:

    supportFragmentManager.inTransaction {
        add(R.id.frameLayoutContent, fragment)
    }