http://blog.csdn.net/leelit/article/details/38776931
之前写的第一篇Fragment实例,和大多数人一開始学的一样。都是通过FragmentTransaction的replace方法来实现,replace方法相当于先移除remove()原来全部已存在的fragments,然后加入add()当前这个fragment。这就导致了一个问题,我们切换一次,然后再切换回来,相当于又一次载入了这个fragment,原来的状态不复存在,这显然与我们的日常使用不符。
想要保存切换后的状态。思路还是非常easy的。我们先加入了若干fragments。切换后将全部fragments都隐藏hide()。并显示show()切换后的fragment就可以。
实例:山寨微信
因为代码较长。这里仅仅讲核心的部分,有兴趣的能够下载源代码来看一下
public class MainActivity extends ActionBarActivity implements OnClickListener { private View weixinLayout, tongxunluLayout, faxianLayout, woLayout; private TextView weixinTv, tongxunluTv, faxianTv, woTv; private ImageView weixinIv, tongxunluIv, faxianIv, woIv; private Fragment1 fragment1; private Fragment2 fragment2; private Fragment3 fragment3; private Fragment4 fragment4; private FragmentManager fm; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化 initViews(); fm = getFragmentManager(); // 初识状态是显示微信 weixinIv.setBackgroundResource(R.drawable.weixin2); weixinTv.setTextColor(getResources().getColor(R.color.green)); showFragment(1); } void initViews() { // 注冊各IamgeView weixinIv = (ImageView) findViewById(R.id.weixin_iv); tongxunluIv = (ImageView) findViewById(R.id.tongxunlu_iv); faxianIv = (ImageView) findViewById(R.id.faxian_iv); woIv = (ImageView) findViewById(R.id.wo_iv); // 注冊各TextView weixinTv = (TextView) findViewById(R.id.weixin_tv); tongxunluTv = (TextView) findViewById(R.id.tongxunlu_tv); faxianTv = (TextView) findViewById(R.id.faxian_tv); woTv = (TextView) findViewById(R.id.wo_tv); // 注冊各Layout weixinLayout = (View) findViewById(R.id.weixin_layout); tongxunluLayout = (View) findViewById(R.id.tongxunlu_layout); faxianLayout = (View) findViewById(R.id.faxian_layout); woLayout = (View) findViewById(R.id.wo_layout); // 各Layout注冊监听器 weixinLayout.setOnClickListener(this); tongxunluLayout.setOnClickListener(this); faxianLayout.setOnClickListener(this); woLayout.setOnClickListener(this); } @Override public void onClick(View arg0) { // TODO Auto-generated method stub // 当点击某个layout时。先清除状态。这里的状态指的是布局里面的图片和文字 clearState(); switch (arg0.getId()) { case R.id.weixin_layout: // 假设点的是微信。将微信布局的图片和文字的颜色变为绿色 weixinIv.setBackgroundResource(R.drawable.weixin2); weixinTv.setTextColor(getResources().getColor(R.color.green)); // 显示微信的fragment showFragment(1); break; case R.id.tongxunlu_layout: tongxunluIv.setBackgroundResource(R.drawable.tongxunlu2); tongxunluTv.setTextColor(getResources().getColor(R.color.green)); showFragment(2); break; case R.id.faxian_layout: faxianIv.setBackgroundResource(R.drawable.faxian2); faxianTv.setTextColor(getResources().getColor(R.color.green)); showFragment(3); break; case R.id.wo_layout: woIv.setBackgroundResource(R.drawable.wo2); woTv.setTextColor(getResources().getColor(R.color.green)); showFragment(4); break; } } public void clearState() { // 未选中时的图片 weixinIv.setBackgroundResource(R.drawable.weixin1); tongxunluIv.setBackgroundResource(R.drawable.tongxunlu1); faxianIv.setBackgroundResource(R.drawable.faxian1); woIv.setBackgroundResource(R.drawable.wo1); // 未选中时字体颜色 weixinTv.setTextColor(getResources().getColor(R.color.black)); tongxunluTv.setTextColor(getResources().getColor(R.color.black)); faxianTv.setTextColor(getResources().getColor(R.color.black)); woTv.setTextColor(getResources().getColor(R.color.black)); } public void showFragment(int index) { FragmentTransaction ft = fm.beginTransaction(); // 想要显示一个fragment,先隐藏全部fragment。防止重叠 hideFragments(ft); switch (index) { case 1: // 假设fragment1已经存在则将其显示出来 if (fragment1 != null) ft.show(fragment1); // 否则是第一次切换则加入fragment1,注意加入后是会显示出来的。replace方法也是先remove后add else { fragment1 = new Fragment1(); ft.add(R.id.content, fragment1); } break; case 2: if (fragment2 != null) ft.show(fragment2); else { fragment2 = new Fragment2(); ft.add(R.id.content, fragment2); } break; case 3: if (fragment3 != null) ft.show(fragment3); else { fragment3 = new Fragment3(); ft.add(R.id.content, fragment3); } break; case 4: if (fragment4 != null) ft.show(fragment4); else { fragment4 = new Fragment4(); ft.add(R.id.content, fragment4); } break; } ft.commit(); } // 当fragment已被实例化,就隐藏起来 public void hideFragments(FragmentTransaction ft) { if (fragment1 != null) ft.hide(fragment1); if (fragment2 != null) ft.hide(fragment2); if (fragment3 != null) ft.hide(fragment3); if (fragment4 != null) ft.hide(fragment4); } }
当我们一開始把微信fragment的ListView下拉到如上图时,切换到通讯录fragment。然后再切换回去微信fragment。此时微信的ListView还是原来的状态。这是由于并不是又一次载入微信fragment,而是将其先hide起来,切换回来后再show出来。
引用上篇文章的fragment生命周期图:
假设是repalce方法,我们切换至当前fragment则进行红线以上的生命周期。切换到其它fragment后进行红线下面的生命周期。
可是。假设我们使用hide()和show()的方法,切换至当前fragment依旧进行红线以上的生命周期,切换到其它fragment后并没有进行其它生命周期,仅仅是简单地隐藏了起来。这样应该非常明了了吧。
源代码:
http://download.csdn.net/detail/leelit/8179147