我如何重构导航抽屉

时间:2019-06-20 07:13:29

标签: android kotlin navigation androidx

我想重构这段代码,因为您可以看到重复出现了很多功能

override fun onNavigationItemSelected(menuItem: MenuItem): Boolean {
        when (menuItem.itemId) {

            R.id.home -> {
                homeFragment = HomeFragment()
                supportFragmentManager
                    .beginTransaction()
                    .replace(R.id.frame_layout, homeFragment)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .commit()
            }

            R.id.loanable -> {
                loanableFragment = LoanableFragment()
                supportFragmentManager
                    .beginTransaction()
                    .replace(R.id.frame_layout, loanableFragment)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .commit()
            }

            R.id.payable -> {
                payableFragment = PayableFragment()
                supportFragmentManager
                    .beginTransaction()
                    .replace(R.id.frame_layout, payableFragment)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .commit()
            }

            R.id.compare_rate -> {
                compareRateFragment = CompareRateFragment()
                supportFragmentManager
                    .beginTransaction()
                    .replace(R.id.frame_layout, compareRateFragment)
                    .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                    .commit()
            }
        }

        drawerLayout.closeDrawer(GravityCompat.START)
        return true
    }

2 个答案:

答案 0 :(得分:1)

您可以使用kotlin扩展功能使代码更清晰。

fun Fragment.replace() {
    supportFragmentManager
             .beginTransaction()
             .replace(R.id.frame_layout, this)
             .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
             .commit()
}

override fun onNavigationItemSelected(menuItem: MenuItem): Boolean { 
    when (menuItem.itemId) {
        R.id.home -> HomeFragment().replace()
        R.id.loanable -> LoanableFragment().replace()
        R.id.payable -> PayableFragment().replace()
        R.id.compare_rate -> CompareRateFragment().replace()
    }
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}

如果您的片段容器ID不同:

infix fun Fragment.replaceTo(id: Int) {
    supportFragmentManager
             .beginTransaction()
             .replace(id, this)
             .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
             .commit()
}

override fun onNavigationItemSelected(menuItem: MenuItem): Boolean { 
     when (menuItem.itemId) {
        R.id.home -> HomeFragment() replaceTo R.id.frame_layout1
        R.id.loanable -> LoanableFragment() replaceTo R.id.frame_layout2
        R.id.payable -> PayableFragment() replaceTo R.id.frame_layout3
        R.id.compare_rate -> CompareRateFragment() replaceTo R.id.frame_layout4
    }
    drawerLayout.closeDrawer(GravityCompat.START)
    return true
}

答案 1 :(得分:1)

为什么不使用枚举和一些很酷的语言功能!

enum class NavigationItem(@IdRes val id: Int, val createFragment: ()-> Fragment) {
  HOME(R.id.home, ::HomeFragment),
  LOANABLE(R.id.loanable, ::LoanableFragment),
  PAYABLE(R.id.payable, ::PayableFragment),
  COMPARE_RATE(R.id.compare_rate, ::CompareRateFragment)
}

override fun onNavigationItemSelected(menuItem: MenuItem) =
  requireNotNull(enumValues<NavigationItem>().find { it.id == menuItem.itemId })
    .createFragment()
    .let { fragment ->
       supportFragmentManager
         .beginTransaction()
         .replace(R.id.frame_layout, fragment)
         .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
         .commit()
       drawerLayout.closeDrawer(GravityCompat.START)
    }.run { true }

仅此而已))

枚举包含菜单itemId和目标片段构造函数引用。该行:

requireNotNull(enumValues<NavigationItem>().find { it.id == menuItem.itemId })

搜索与所选id具有相同menuItem的条目的枚举。如果未找到任何条目,则引发异常。行:

createFragment()

仅从枚举条目中调用片段的构造函数引用,从而创建新的片段实例。碎片交易应该是可以理解的。最后一行:

run { true }

从函数返回true,就像在原始代码中一样。