zoukankan      html  css  js  c++  java
  • Android组件:Fragment切换后保存状态

    之前写的第一篇Fragment实例,和大多数人一开始学的一样,都是通过FragmentTransaction的replace方法来实现,replace方法相当于先移除remove()原来所有已存在的fragments,然后添加add()当前这个fragment。这就导致了一个问题,我们切换一次,然后再切换回来,相当于重新加载了这个fragment,原来的状态不复存在,这显然与我们的日常使用不符。想要保存切换后的状态,思路还是很简单的,我们先添加了若干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

  • 相关阅读:
    linux运维、架构之路-MySQL备份与恢复(四)
    linux运维、架构之路-MHA高可用方案
    Tensorflow环境安装
    Sublime Text3 旧版本下载以及破解激活方式
    《SDN期末作业——实现负载均衡》
    SDN第六次上机作业
    自定义Toast的出现样式
    SDN第五次上机作业
    SDN第4次上机作业
    Context与ApplicationContext的区别
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/4617862.html
Copyright © 2011-2022 走看看