在初次接触安卓总是会迷惑于各种fragment和activity之间的跳转,以为Intent可以解决所有跳转问题。
由于对于之前学习过的知识,我们对于fragment之间的跳转都是通过在fragment外部的一个activity的事件监听来控制fragment页面的切换。但是当我要在fragment里面添加监听事件跳转的时候,就遇到了问题,以为用Intent可以解决,结果会报错。后来了解到Inten是在在不同的 Activity 之间进行跳转或传递数据。而在同一个 Activity 中的不同 Fragment 之间的跳转或通信通常使用 FragmentManager 或其他方式来实现。
比如这一串代码就是我们常用的在acitivty里面用来切换fragment的代码(展示callFragment,隐藏另在两个Fragment)。
getSupportFragmentManager().beginTransaction().show(callFragment).hide(messageFragment).hide(dynamicsFragment).commit();
想到这个代码可以用来切换不同的fragment我就立即把他复制到我的fragment的监听事件中去,结果依旧是报错,只有在activity中getFragmentManager()才生效。
那我又在想,可不可以把这段代码封装成一个方法,让我在fragment里面去调用它呢?
public void SwitchToContact(){
getSupportFragmentManager().beginTransaction().show(callFragment).hide(messageFragment).hide(dynamicsFragment).commit();
}
方法已经封装好。问题又出现了,如何在fragment里面去调用它呢?难道是重新new 一个Mainactivity的类型再去调用吗? 如果你这么做了,会出现一个这样的错误
java.lang.IllegalStateException: FragmentManager has not been attached to a host.
这个错误通常出现在 Fragment 的生命周期方法之外调用 FragmentManager 的情况下,或者在 Fragment 还没有关联到 Activity 时就尝试使用 FragmentManager。在 Fragment 的生命周期方法之外使用 FragmentManager 可能会导致这个错误。
我们的思路应该获取当前 Fragment 所依附的 Activity 的实例,然后再调用这个方法。那么怎么获取呢?requireActivity()这个方法可以帮助到你,然后还要进行一个强制类型转换。所以最后在fragment里面的代码就应该是这样的。
((MainActivity)requireActivity()).SwitchToContact();
这样你就可以成功调用MainActivity里面的跳转方法了;
那么对于不同的Activity要跳转到具体的Fragment其实也就很容易实现了,你可以使用Intent跳转到当前管理那个Fragment的activity,并且使用intent传一个值过去。
Intent intent = new Intent(HIstoryTestActivity.this,MainActivity.class);
intent.putExtra("id",1);
startActivity(intent);
然后在MainActivity去接收这个跳转带来的值,进行逻辑判断,判断正确则调用MainActivity的跳转fragment方法。
if(getIntent().getIntExtra("id",0)==1){
siwtchToTestFragment();
}
这样就可以完成跳转了。
以上是我的经验总结,如有错误,欢迎大家批评改正!