欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android中Fragment相互切换间不被回收的实现方法

程序员文章站 2023-01-03 11:07:37
前言 android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视。针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套app,然后拷贝一份,修改布局以适...

前言

android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视。针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套app,然后拷贝一份,修改布局以适应平板神马超级大屏的。难道无法做到一个app可以同时适应手机和平板么,当然了,必须有啊。fragment的出现就是为了解决这样的问题。

如今市面上的应用基本上都是单activity+多fragment实现的了,而这类app都有在相互切换时不被回收,即切换回原来的fragment时还是原先的状态,这就是这里要实现的了。

这里使用fragment的add()show()hide()实现,即显示和隐藏,这样原来的fragment就不会被销毁了。

二话不说,贴代码,代码是最好的老师。

示例代码(注释还算详细了)

public class mainactivity extends appcompatactivity implements view.onclicklistener {

 private imageview ibone;
 private imageview ibtwo;
 private imageview ibthree;
 
 private fragmentmanager mfm;
 private arraylist<fragment> mfragmentlist = new arraylist<fragment>();
 private string[] mfragmenttaglist = {"onefragment", "twofragment", "threefragment"};
 private fragment mcurrentfragmen = null; // 记录当前显示的fragment

 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  setcontentview(r.layout.activity_main);
  
  initview();
  initdata();
  
 }

 private void initdata() {
  onefragment onefragment = new onefragment();
  twofragment twofragment = new twofragment();
  threefragment threefragment = new threefragment();
  mfragmentlist.add(0, onefragment);
  mfragmentlist.add(1, twofragment);
  mfragmentlist.add(2, threefragment);

  mcurrentfragmen = mfragmentlist.get(0);

  // 初始化首次进入时的fragment
  mfm = getfragmentmanager();
  fragmenttransaction transaction = mfm.begintransaction();
  transaction.add(r.id.fl_show, mcurrentfragmen, mfragmenttaglist[0]);
  transaction.commitallowingstateloss();
 }

 // findviewbyid
 private void initview() {
  ibone = (imageview)findviewbyid(r.id.ib_one);
  ibtwo = (imageview)findviewbyid(r.id.ib_two);
  ibthree = (imageview)findviewbyid(r.id.ib_three);

  ibone.setonclicklistener(this);
  ibtwo.setonclicklistener(this);
  ibthree.setonclicklistener(this);
 }

 @override
 public void onclick(view view) {
  switch (view.getid()){
   case r.id.ib_one:
    switchfragment(mfragmentlist.get(0), mfragmenttaglist[0]);
    break;
   case r.id.ib_two:
    switchfragment(mfragmentlist.get(1), mfragmenttaglist[1]);
    break;
   case r.id.ib_three:
    switchfragment(mfragmentlist.get(2), mfragmenttaglist[2]);
    break;
  }
 }

 // 转换fragment
 void switchfragment(fragment to, string tag){
  if(mcurrentfragmen != to){
   fragmenttransaction transaction = mfm.begintransaction();
   if(!to.isadded()){
    // 没有添加过:
    // 隐藏当前的,添加新的,显示新的
    transaction.hide(mcurrentfragmen).add(r.id.fl_show, to, tag).show(to);
   }else{
    // 隐藏当前的,显示新的
    transaction.hide(mcurrentfragmen).show(to);
   }
   mcurrentfragmen = to;
   transaction.commitallowingstateloss();

  }
 }

 // 当activity非正常销毁时被调用
 @override
 public void onsaveinstancestate(bundle outstate, persistablebundle outpersistentstate) {
  super.onsaveinstancestate(outstate, outpersistentstate);
  // 重置fragment,防止当内存不足时导致fragment重叠
  updatefragment(outstate);
 }

 // 重置fragment
 private void updatefragment(bundle outstate) {

  mfm = getfragmentmanager();
  if(outstate == null){
   fragmenttransaction transaction = mfm.begintransaction();
   onefragment onefragment = new onefragment();
   mcurrentfragmen = onefragment;
   transaction.add(r.id.fl_show, onefragment, mfragmenttaglist[0]).commitallowingstateloss();
  }else{
   // 通过tag找到fragment并重置
   onefragment onefragment = (onefragment) mfm.findfragmentbytag(mfragmenttaglist[0]);
   twofragment twofragment = (twofragment) mfm.findfragmentbytag(mfragmenttaglist[1]);
   threefragment threefragment = (threefragment) mfm.findfragmentbytag(mfragmenttaglist[2]);
   mfm.begintransaction().show(onefragment).hide(twofragment).hide(threefragment);
  }
 }
}

我以前对于这种需求是在一个activity中使用relativelayout,在其中加入多个布局(类似fragment),当点击下方tab时设置布局的visibility的,思想是一样的,但这样实现起来很是丑陋,所以不建议使用。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持