【问题标题】:How can i refactor the navigation drawer我如何重构导航抽屉
【发布时间】:2019-06-20 07:13:29
【问题描述】:

我想重构这部分代码,你可以看到有很多函数重复

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
    }

【问题讨论】:

    标签: android kotlin navigation androidx


    【解决方案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
    }
    

    【讨论】:

    • 有趣的代码,也是我第一次看到infix被使用。感谢分享。
    【解决方案2】:

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

    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 })
    

    在枚举中搜索与所选menuItem 具有相同id 的条目。如果没有找到条目,则抛出异常。线路:

    createFragment()
    

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

    run { true }
    

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

    【讨论】:

      猜你喜欢
      • 2018-12-22
      • 2018-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多