必威-必威-欢迎您

必威,必威官网企业自成立以来,以策略先行,经营致胜,管理为本的商,业推广理念,一步一个脚印发展成为同类企业中经营范围最广,在行业内颇具影响力的企业。

replace一般单独出现,按记录的context碎片show()某一

2019-09-19 00:20 来源:未知

具有的稿子都是上下一心的经历和小结,借使有不当的位置迎接留言指正,避防影响另外的黄金时代。

Fragment add replace 区别

首先获得FragmentTransaction对象:FragmentTransaction transaction = getFragmentManager().beginTransaction();

replace是二个替换的长河,意思是remove掉当前的fragment,重新开头化三个new fragment实行交换,会重复完全执行新的fragment的生命周期。replace()那些方法只是在上四个Fragment不再需求时行使的方便方法
在Activity onCreate()中加多Fragment的时候势必不要忘了检查一下savedInstanceState,通过savedInstanceState是还是不是为空来推断填充当前的情状。假使为空,则填充当前的context,若不为空,大家能够通过add时候的tag来找到呼应的fragmemt,全体的零散实例都是存在于内存中的,只是由于错失引用再一次启航它的引用被销毁了。大家只要找到赋值给相应的零碎,再通过保留的情形来hide和show就好了。比较易于领会
咱俩那边运用的方法是:通过getSupportFragmentManager()找到全数的 Fragment,按记录的context碎片show()某一个Fragment,hide()别的具备的fragment。

FragmentTransaction API文档(供给翻墙)

上一篇有关系三个知识点:

首先猎取FragmentTransaction对象:FragmentTransaction transaction = getFragmentManager().beginTransaction();

二种格局差异之处是或不是要清空容器再增添fragment的分别,用法上add合营hide或是remove使用,replace一般单独出现。

transaction.commit();
transaction.commitAllowingStateLoss();
两岸都足以付出fragment的操作,独一的例外是第三种格局,允许错失一些分界面包车型大巴动静和音讯,差相当的少全部的开辟者都赶过过如此的谬误:不可能在activity调用了onSaveInstanceState之后再实践commit(),这种十分时得以知晓的,分界面被系统回收(分界面已经空头支票),为了在下一次张开的时候恢复生机原先的表率,系统为大家保留分界面包车型大巴装有情状,这年我们再去修改分界面理论上必将是不允许的,所以为了幸免这种特别,要利用第三种办法。

常用方法详解

transaction.commit();transaction.commitAllowingStateLoss();

二种艺术不一致之处是不是要清空容器再增多fragment的区别,用法上add同盟hide或是remove使用,replace一般单独出现。

添加

貌似会同盟hide使用:transaction.add(Escort.id.fragment_container, oneFragment).hide(twoFragment).commit();

1.首先个参数是容器id, 第一个参数是要增加的fragment,增多不会清空容器中的内容,不停的往里面增加

2.不容许增加同三个fragment实例,这是特别关键的性状。如若八个fragment已经跻身的话,再度增添的话会报极度错误的。

3.增多步入的fragment都以可知的(visible),后增多的fragment会映以往先增多的fragment上面,在绘制分界面包车型大巴时候会绘制全数可知的view

4.所以大大多add都是和hide恐怕是remove同临时候采取的。这样能够省去绘制分界面包车型地铁时日,节省外部存款和储蓄器消耗,是推荐的用法。

拉长和替换,是最常用的多个法子,从字面包车型客车情趣上看能够特别显明的接头,增添正是往容器中丰硕(add),替换(replace)则是把容器清空再增多,相当于把容器中的全部剧情都替换掉。如若三个fragment已经跻身的话,再度增多的话会报极度错误的,不另行增多同一fragment,那是那一个首要的风味。
累加进去的fragment都以可知的(visible),后增加的fragment会议及展览示在先增加的fragment上边,在绘制界面的时候会绘制全数可知的view,所以大繁多add都是和hide大概是remove同时选择的
轮换会把容器中的所以内容全都替换掉,有一部分app会动用那样的做法,保持唯有二个fragment在彰显,缩短了界面包车型的士层级关系。
差别之处

1. add(int containerViewId, Fragment fragment, String tag)、 remove(Fragment fragment)

API文书档案表明:

add(int containerViewId, Fragment fragment, String tag) : 向Activity state中增添一个Fragment。

remove(Fragment fragment) : 移除三个早已存在的Fragment.

补充:

  1. add方法 : 参数containerViewId一般会传Activity中有个别视图容器的id。如若containerViewId传0,则那么些Fragment不会被放置在多少个容器中(不要感觉Fragment没增加进去,只是大家增添了贰个尚无视图的Fragment,这几个Fragment能够用来做一些像样于service的后台工作)。

  2. remove方法 : Fragment被remove后,Fragment的性命周期会一贯进行完onDetach,之后Fragment的实例也会从FragmentManager中移除。

  3. 下边看贰个使用add方法增加Fragment的坑,相信广大人都遭逢过 -> “Fragment被再次增添的难点”

Fragment被另行增多的难题:现行反革命,大家承袭上一篇Fragment升级 - 基本用法中“Fragment动态加载”的事例,给布局容器(fl_main)附加三个点击事件,Toast当前Activity中的全部Fragment音信...

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager().beginTransaction().add(R.id.fl_main, new ContentFragment(), null).commit();

        findViewById(R.id.fl_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, getSupportFragmentManager().getFragments().toString(), Toast.LENGTH_LONG).show();
            }
        });
    }
}

接下去运维一下主次,大家开展三遍横竖屏切换(模拟Activity的老大重启),而且每回切换都点击下布局容器,Toast下消息...

add_fragment_bug.gif

(PS:因拍戏软件原因,手提式有线电话机横竖屏切换显得有一点别扭,各位见谅,Toast看清就Ok)

现象:大家发掘Activity里的Fragment数量在相连的增添。

原因:实在,当大家Activty被这一个销毁时,Activity会对本人状态举办保存(那其中包涵了大家增多的Fragment)。在Activity被再度创造时,又对我们事先封存的Fragment实行了过来,不过大家在onCreate时却又增多了1次Fragment,所以大家的Fragment数量在相连增添...

加多Fragment的不易姿势:(2种消除办法)

缓和形式1(推荐):增添Fragment前检查是不是有保留的Activity状态。若无动静保存,表明Acitvity是第1次被创设,大家增多Fragment。假如有气象保存,表达Activity刚刚出现过十二分被灭绝过,将来正值苏醒,我们不再增添Fragment。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction().add(R.id.fl_main, new ContentFragment(), null).commit();
        }

        findViewById(R.id.fl_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, getSupportFragmentManager().getFragments().toString(), Toast.LENGTH_LONG).show();
            }
        });
    }
}

运作下程序,查看下效果:

add_fragment.gif

斩草除根办法2(不推荐):Activity在每趟相当退出前,移除当前有所的Fragment。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getSupportFragmentManager().beginTransaction().add(R.id.fl_main, new ContentFragment(), null).commit();

        findViewById(R.id.fl_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MainActivity.this, getSupportFragmentManager().getFragments().toString(), Toast.LENGTH_LONG).show();
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        if(getSupportFragmentManager().findFragmentById(R.id.fl_main) != null) {
            getSupportFragmentManager().beginTransaction().remove(getSupportFragmentManager().findFragmentById(R.id.fl_main)).commit();
        }
        super.onSaveInstanceState(outState);
    }
}

第2种缓慢解决方法的运营效果和第1种同等,就不再上海教室了...

比较之下三种缓和方法:莫不我们备感方法2越来越客观,然则本身大概引入第1种方法。

原因1:第2种格局很坑,移除操作只好放在super.onSaveInstanceState(outState)在此之前,之后移除必要选取commitAllowingStateLoss来替换commit,可是此时的移除操作会在回复时错过。

原因2:实质上第2种办法还应该有个Bug,把手提式有线电话机灭屏再张开,会发觉Fragment消失了,因为手提式有线电话机灭屏会调用onSaveInstanceState那么些方法。

参与第2种格局是为了证实remove的用法,以及Fragment手动移除的坑。简单的讲,Fragment的移除操作须要足履实地。

最终补充有些: add操作能够施行数十次,然后一并付诸(比如,代码如下)。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if(savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fl_main, new ContentFragment(), null)
                    .add(R.id.fl_main, new ContentFragment(), null)
                    .add(R.id.fl_main, new ContentFragment(), null)
                    .commit();
        }
    }
}

末段运转下程序,我们用Hierarchy Viewer看下视图的档次结构。

viewer4.png

和我们想像的大同小异,大家的Activity视图容器(fl_main)里带有了3个Fragment的视图。


先提前证实:两个都足以提交fragment的操作,独一的两样是第三种办法,允许遗失一些分界面包车型地铁情景和新闻,大约具有的开辟者都高出过如此的不当:不或许在activity调用了onSaveInstanceState之后再进行commit(),这种特别时得以清楚的,分界面被系统回收,为了在下一次开垦的时候苏醒原本的轨范,系统为我们保留分界面包车型大巴具备意况,那一年大家再去修改分界面理论上一定是差异意的,所以为了幸免这种非常,要使用第二种艺术。

添加

替换

transaction.replace(R.id.fragment_container, oneFragment).commit();

1.轮换会把容器中的全体剧情全都替换掉,有一部分app会动用那样的做法,保持独有八个fragment在突显,减弱了分界面的层级关系。

同样之处:每一趟add和replace都要走贰遍fragment 的周期。

 其实fragment一般不会这么简单利用,replace的利用情形一般相当少,大比比较多是加多(add)和彰显(show)协作遮掩(hide)来使用,那样首先防止同一档案的次序的fragment的重复增添,提示开采者使用单例情势,已经增加过的fragment相当多动静没有供给再一次增多,况且还应该有把生命周期再走一回,那是一种比较浪费的做法

 

最合适的管理方式是这么的:

1.在add的时候,加上三个tab参数
transaction.add(R.id.content, IndexFragment,”Tab1″);
2.然后当IndexFragment援引被回收置空的话,先经过
IndexFragment=FragmentManager.findFragmentByTag(“Tab1″);
找到相应的引用,然后继续上边的hide,show;

正是是不是要清空容器再增加fragment的分别,用法上add协作hide或是remove使用,replace一般单独出现。
一样之处

2. replace(int containerViewId, Fragment fragment)、replace(int containerViewId, Fragment fragment, String tag)####

API文书档案表明:轮换三个已被增多进视图容器的Fragment。

补充:

  1. 方式效果:类似于先remove掉视图容器全部的Fragment,再add多少个想要增多的Fragment。

(举个简单的事例 - 代码如下,大家add二遍,replace三遍)

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager().beginTransaction()
                .add(R.id.fl_main, new ContentFragment(), null)
                .add(R.id.fl_main, new ContentFragment(), null)
                .add(R.id.fl_main, new ContentFragment(), null)
                .replace(R.id.fl_main, new ContentFragment(), null)
                .commit();
    }
}

用Hierarchy Viewer看下视图的层次结构:

viewer6.png

大家开采只有三个Fragment的视图,表明在此以前add的Fragment都在replace时被视图容器移除了。


TAG标签:
版权声明:本文由必威发布于必威-编程,转载请注明出处:replace一般单独出现,按记录的context碎片show()某一