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的,思想是一样的,但这样实现起来很是丑陋,所以不建议使用。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持