记录一次代码演变过程——35行变24行

来自:鹏小轩

1 最初的实现

一般Android应用首页底部都分几个tab模块,点击一个tab就跳转到相应的功能点模块去,所以代码里一般都会有一个方法pageTo(),如下:

private void pageTo(int pageIndex) {
    if (pageIndex == mCurrentPage) return;
    mCurrentPage = pageIndex;

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    hideFragment(transaction);

    switch (pageIndex) {
        case PAGE_POSITION_HOME:
            if (mHomeFragment == null) {
                mHomeFragment = new HomeFragment();
                transaction.add(R.id.fragment_container, mHomeFragment);
            } else {
                transaction.show(mHomeFragment);
            }
            transaction.commit();
            break;

        case PAGE_POSITION_MESSAGE:
            if (mMessageFragment == null) {
                mMessageFragment = new MessageFragment();
                transaction.add(R.id.fragment_container, mMessageFragment);
            } else {
                transaction.show(mMessageFragment);
            }
            transaction.commit();
            break;

        case PAGE_POSITION_PERSON:
            if (mUserFragment == null) {
                mUserFragment = new UserFragment();
                transaction.add(R.id.fragment_container, mUserFragment);
            } else {
                transaction.show(mUserFragment);
            }
            transaction.commit();
            break;
    }
}

咋一看,好像没有问题,但是总是觉得还有重复的代码在里面。比如说,else里面的所有逻辑其实重复的。上面的代码,我们认真分析就能够知道,一共做了两件事。

第一,初始化fragment;
第二,提交显示fragment。(这里可以提取出来)

2 第二个版本

顺着以上思路,我们很容易的编写了第二个版本。

private void pageTo(int pageIndex) {
    if (pageIndex == mCurrentPage) return;
    mCurrentPage = pageIndex;

    FragmentTransaction transaction = getSupportFragmentManager()
                       .beginTransaction();
    hideFragment(transaction);

    switch (pageIndex) {
        case PAGE_POSITION_HOME:
            showFragment(PAGE_POSITION_HOME, transaction, mHomeFragment);
            break;

        case PAGE_POSITION_MESSAGE:
            showFragment(PAGE_POSITION_MESSAGE, transaction
                      , mMessageFragment);
            break;

        case PAGE_POSITION_PERSON:
            showFragment(PAGE_POSITION_PERSON, transaction
                      , mUserFragment);
            break;
    }
}

private void showFragment(int index, FragmentTransaction transaction
            , BaseFragment fragment)
 
{
    if (fragment == null) {
        // 当传入的fragment没有被初始化
        if (index == PAGE_POSITION_HOME) {
            fragment = mHomeFragment = new HomeFragment();
        } else if (index == PAGE_POSITION_MESSAGE) {
            fragment = mMessageFragment = new MessageFragment();
        } else {
            fragment = mUserFragment = new UserFragment();
        }
        transaction.add(R.id.fragment_container, fragment);

    } else {
        transaction.show(fragment);
    }
    transaction.commit();
}

这个版本主要是提取出了初始化和显示fragment的代码,初始化已经没有办法更改得更加简单,显示fragment这段代码就可以共用起来。

但是看到这里,发现另一个问题,就是在pageTo()和showFragment()这两个方法中,都对index进行了判断。其实是重复的,于是就有了第三个版本。

3 第三版本

private SparseArray<BaseFragment> fragmentMap = new SparseArray<>();

private void pageTo(int pageIndex) {
    if (pageIndex == mCurrentPage) return;
    mCurrentPage = pageIndex;

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
    hideFragment(transaction);

    showFragment(pageIndex, transaction, fragmentMap.get(pageIndex));

}

private void showFragment(int index, FragmentTransaction transaction, BaseFragment fragment) {
    if (fragment == null) {
        // 当传入的fragment没有被初始化
        if (index == PAGE_POSITION_HOME) {
            fragment = mHomeFragment = new HomeFragment();
        } else if (index == PAGE_POSITION_MESSAGE) {
            fragment = mMessageFragment = new MessageFragment();
        } else {
            fragment = mUserFragment = new UserFragment();
        }
        transaction.add(R.id.fragment_container, fragment);
        // 缓存住已经初始化的fragment,以便点击tab时传入到此方法中。
        fragmentMap.put(index, fragment);

    } else {
        transaction.show(fragment);
    }
    transaction.commit();
}

利用集合来缓存住 fragment,这样就可以省去一次判断。到此,大功告成,代码瞬间感觉清爽了许多,迷之缩进也少了。


精雕细琢,就是你思考行走的路径。

推荐↓↓↓
安卓开发
上一篇:ByteDance 字节跳动 Android 高工面试记 下一篇:Android 仿抖音实现动态壁纸