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,这样就可以省去一次判断。到此,大功告成,代码瞬间感觉清爽了许多,迷之缩进也少了。
精雕细琢,就是你思考行走的路径。