Android开发之Fragment重叠问题:

本文探讨了在Android开发中,使用hide()和show()替代replace()进行Fragment切换的技术细节及优势,并提供了解决页面重叠问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

android开发中,为了提升性能,我们会用hide()和show(),替代replace(),然而我们进程遇到,使用Fragnment 嵌入到Activity中时,如果遇到bug,app闪退会导致页面的重叠:那么问题来了,为什么使用hide和show的性能会好于replace():

1:使用replace方法把原有的Fragment替换掉;

public class MainActivity extends ActionBarActivity implements OnClickListener
{

    private Button ott, tto;
    Fragment1 f1;
    Fragment2 f2;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ott = (Button) findViewById(R.id.ott);
        tto = (Button) findViewById(R.id.tto);

        ott.setOnClickListener(this);
        tto.setOnClickListener(this);

        f1 = new Fragment1();
        f2 = new Fragment2();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.fl, f1);
        ft.commit();
    }

    @Override
    public void onClick(View arg0)
    {
        if (arg0.getId() == R.id.ott)
        {

            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.fl, f2);
            ft.commit();

        }
        else if (arg0.getId() == R.id.tto)
        {

            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.fl, f1);
            ft.commit();

        }
    }
}


 

 

(1)程序刚刚启动

(2)Fragment1 ——>Fragment2,生命周期为:

(3)Fragment2 ——>Fragment1,生命周期为:

(4)再次Fragment1 ——>Fragment2,生命周期为:

如上,若频繁地replace Fragment来切换,会不断创建新实例,销毁旧的,浪费资源,无法重用。

 2、使用hide和show方法,把已经添加过的Fragment隐藏或显示出来。

 

public class MainActivity extends ActionBarActivity implements OnClickListener
{

    private Button ott, tto;
    Fragment1 f1;
    Fragment2 f2;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ott = (Button) findViewById(R.id.ott);
        tto = (Button) findViewById(R.id.tto);

        ott.setOnClickListener(this);
        tto.setOnClickListener(this);

        f1 = new Fragment1();
        f2 = new Fragment2();
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.add(R.id.fl, f1);
        ft.commit();
    }

    @Override
    public void onClick(View arg0)
    {
        if (arg0.getId() == R.id.ott)
        {

            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.fl, f2);
            ft.commit();

        }
        else if (arg0.getId() == R.id.tto)
        {

            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.fl, f1);
            ft.commit();

        }
    }
}



 

此时情况会发生什么变化呢?
(1)程序刚刚启动


(2)Fragment1 ——>Fragment2,生命周期为:

(3)Fragment2 ——>Fragment1,不打印任何生命周期
(4)再次Fragment1 ——>Fragment2,不打印任何生命周期

使用场景:如果Fragment需要重用或者不断切换,可以使用该方法提高性能。使用使用show和hide会出现重叠

那么如何解决重叠呢:
我找到了原因,在我切换到其他app的时候,fragment所在activity已经被销毁。并且通过

@Override  
public void onSaveInstanceState(Bundle outState) {  
    // TODO Auto-generated method stub        
    Log.v("LH", "onSaveInstanceState"+outState);  
    super.onSaveInstanceState(outState);  
}


这个方法保存了相关的数据。

   当我再次回到这个app的时候,通过onCreate中的参数savedInstanceState恢复了之前的fragment。此时的FragmentTransaction中的相当于又再次add了fragment进去的,之前保存的fragment也还在。hide()和show()方法对之前保存的fragment已经失效了。所以出现了重叠的现象。

第一种比较方便的解决方法时:

直接在包含Fragment的Activity中复写

public void onSaveInstanceState(Bundle outState) {  
    // TODO Auto-generated method stub       
    //Log.v("LH", "onSaveInstanceState"+outState);  
    //super.onSaveInstanceState(outState);   //将这一行注释掉,阻止activity保存fragment的状态
}


第二种保存app崩溃时的数据:

  
 @Override
    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {
        super.onSaveInstanceState(outState, outPersistentState);
        outState.putString("TAG",tag);
    }
 //onCreate的时候调用
 @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
       if (savedInstanceState!=null){
           tag= savedInstanceState.getString("TAG");
           int i = Integer.parseInt(tag);
           fragmentTransaction.remove(fragments[i]);
       }
      }

通过remove把之前的移除掉,建立新的页面:

3.保存app崩溃时的数据:

 

1.页面切换代码
@Override
	public void callTabFragment(int id) {
		id2 = id;
		tab1=id;
		ft = getSupportFragmentManager().beginTransaction();
		hide(ft);
		switch (id) {
		case R.id.home_item_tab:
			if (homeFargment == null) {
				homeFargment = new HomeFargment();
				ft.add(R.id.fl, homeFargment,R.id.home_item_tab+"");
			} else {
				ft.show(homeFargment);
			}
			tab=R.id.home_item_tab;
			break;

		case R.id.shaidan_item_tab:	
			if (shaidanFargment == null) {
				shaidanFargment = new JiaMengFargment();
				ft.add(R.id.fl, shaidanFargment,R.id.shaidan_item_tab+"");
			} else {
				ft.show(shaidanFargment);
			}
			tab=R.id.shaidan_item_tab;
			break;
		case R.id.gwc_item_tab:

			if (gwcFargment == null) {
				gwcFargment = new GwcFargment();
				ft.add(R.id.fl, gwcFargment,R.id.gwc_item_tab+"");
			} else {
				ft.show(gwcFargment);
			}
			tab=R.id.gwc_item_tab;
			break;
		case R.id.my_item_tab:
			if (meFargment == null) {
				meFargment = new MeFargment();
				ft.add(R.id.fl, meFargment,R.id.my_item_tab+"");
			} else {
				ft.show(meFargment);
			}
			tab=R.id.my_item_tab;
			break;

		}
		ft.commit();
	}
2.保存崩溃前的数据:
@Override
	protected void onSaveInstanceState(Bundle outState) {
		// TODO Auto-generated method stub
		//super.onSaveInstanceState(outState);
		outState.putInt("tab1", tab1);
		outState.putInt("tab", tab);
	}
	
 3.恢复数据
@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		if (savedInstanceState!=null) {
			tab=savedInstanceState.getInt("tab");
			callTabFragment(tab);
			//切换背景
		}
		super.onRestoreInstanceState(savedInstanceState);
	}



 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值