Activity切换时,相信大家都知道是通过栈的形式,不断压栈出栈,在Fragment的时候,如果你不是手动开启回退栈,它是直接销毁再重建,但如果将Fragment任务添加到回退栈,情况就会不一样了,它就有了类似Activity的栈管理方式。
public void startToFragment(Context context, int container, Fragment newFragment) {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(container, newFragment);
transaction.addToBackStack(context.getClass().getName());
transaction.commit();
}
1.fragment1 --> fragment2
Fragment2 fragment2 = new Fragment2 ();
startToFragment(getActivity(), R.id.layout_container, fragment2 );
2.fragment2 --> fragment1
getActivity().getFragmentManager().popBackStack();
3.fragment2 --> fragment3
Fragment3 fragment3 = new Fragment3 ();
startToFragment(getActivity(), R.id.layout_container, fragment3 );
4.fragment3 --> fragment1
//回退栈中某个Fragment之上的所有Fragment
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.popBackStackImmediate(
MainActivity.class.getName(), FragmentManager.POP_BACK_STACK_INCLUSIVE);
通常,Fragment 与 Activity 通信存在三种情形:
Activity 操作内嵌的 Fragment
Fragment 操作宿主 Activity
Fragment 操作同属 Activity中的其他 Fragment
在Android中我们可以通过以下几种方式优雅地实现Activity和fragment之间的通信:
Handler
广播
EventBus
接口回调
Bundle和setArguments(bundle)
public class MainActivity extends FragmentActivity{
//声明一个Handler
public Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//相应的逻辑处理代码
}
}
}
public class MainFragment extends Fragment{
//保存Activity传递的handler
private Handler mHandler;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if(activity instance MainActivity){
mHandler = ((MainActivity)activity).mHandler;
}
}
}
这种方式的缺点:
Fragment对具体的Activity存在耦合,不利于Fragment复用
不利于维护,若想删除相应的Activity,Fragment也得改动
没法获取Activity的返回数据
所以一般不建议使用这种方法。
在 Activity 中注册广播接收器,在 Fragment中发送广播:
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_NAME)) {
String msg = intent.getStringExtra("msg");
Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
}
}
};
public void registerBoradcastReceiver() {
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(ACTION_NAME);
registerReceiver(mBroadcastReceiver, myIntentFilter);
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mBroadcastReceiver);
}
MainActivity
//注册订阅者
EventBus.getDefault().register(this);
//定义接收信息的方法
@Subscribe
public void onEventMainThread(UserEvent event) {
btn.setText(event.getUserName());
service_tv.setText(event.getUserName());
}
Fragment发送信息
UserEvent event=new UserEvent();
EventBus.getDefault().post(event);
在 Fragment 中定义一个接口
调用接口中的抽象方法
在 Activity 中实现接口,并具体实现接口中的方法,完成通信
初始化Fragment实例并setArguments:
DiscoverFragment discoverFragment = new DiscoverFragment();
Bundle bundle = new Bundle();
bundle.putString("email", email);
discoverFragment.setArguments(bundle);
在Fragment中拿到Arguments:
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_discover, null);
Bundle bundle = getArguments();
//这里就拿到了之前传递的参数
email = bundle.getString("email");
return view;
}
Activity 在重建的时候会恢复其包含的 FragmentManager ,FragmentManager 又会恢复其管理的 Fragment ,同理 Fragment 也会恢复其包含的 FragmentManager,层层递进,直到全部恢复
避免显示错乱
避免重复添加
避免多余的内存占用
优化界面启动速度等
使用FragmentPagerAdapter 时,Fragment对象会一直存留在内存中,所以当有大量的显示页时,就不适合用FragmentPagerAdapter了,FragmentPagerAdapter 适用于只有少数的page情况,像选项卡。
这个时候你可以考虑使用FragmentStatePagerAdapter ,当使用FragmentStatePagerAdapter 时,如果Fragment不显示,那么Fragment对象会被销毁,(滑过后会保存当前界面,以及下一个界面和上一个界面(如果有),最多保存3个,其他会被销毁掉)
但在回调onDestroy()方法之前会回调onSaveInstanceState(Bundle outState)方法来保存Fragment的状态,下次Fragment显示时通过onCreate(Bundle savedInstanceState)把存储的状态值取出来,FragmentStatePagerAdapter 比较适合页面比较多的情况,像一个页面的ListView 。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章