前言
Activity切换时,是通过栈的形式,不断压栈出栈。对于fragment如果你不手动开启回退栈,它是直接销毁再重建,但如果将fragment任务添加到回退栈,情况就会不一样了,它就有了类似Activity的栈管理方式。
回顾
一、fragment回退栈方法简介
addToBackStack(tag); 将Fragment添加到回退栈中
popBackStack(); 清除回退栈中栈顶的Fragment
popBackStack(String tag, int i );
如果i=0,回退到该tag所对应的Fragment层
如果i=FragmentManager.POP_BACK_STACK_INCLUSIVE,回退到该tag所对应的Fragment的上一层
popBackStackImmediate 立即清除回退栈中栈顶Fragment
getBackStackEntryCount(); 获取回退栈中Fragment的个数
getBackStackEntryAt(int index) 获取回退栈中该索引值下的Fragment
举例:逐层退出回退栈效果代码的实现
public class AddFragmentActivity extends FragmentActivity implements MessageFragment.MessageListener {
private FrameLayout mFrameLayout;
private RadioGroup mRg;
private RadioButton mRbHome;
private RadioButton mRbCommunity;
private RadioButton mRbMessage;
private RadioButton mRbMe;
private List<Fragment> mFragments = new ArrayList<>();
private HomeFragment homeFragment;
private CommunityFragment communityFragment;
private MessageFragment messageFragment;
private MeFragment meFragment;
private FragmentManager mSupportFragmentManager;
private FragmentTransaction mTransaction;
private TextView mTvMain;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fragment);
mFrameLayout = findViewById(R.id.frameLayout);
mRg = findViewById(R.id.rg_main);
mRbHome = findViewById(R.id.rb_home);
mRbCommunity = findViewById(R.id.rb_community);
mRbMessage = findViewById(R.id.rb_message);
mRbMe = findViewById(R.id.rb_me);
mTvMain = findViewById(R.id.tv_main);
initView();
}
private void initView() {
mSupportFragmentManager = getSupportFragmentManager();
mTransaction = mSupportFragmentManager.beginTransaction();
//设置默认选中首页
mRg.check(R.id.rb_home);
homeFragment = new HomeFragment();
//创建Bundle对象,并存储数据
Bundle bundle = new Bundle();
bundle.putString("home", "Home");
homeFragment.setArguments(bundle);
mFragments.add(homeFragment);
hideOthersFragment(homeFragment, true, "homefragment");
mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
switch (checkedId) {
case R.id.rb_home: //首页
hideOthersFragment(homeFragment, false, "homefragment");
break;
case R.id.rb_community: //发现
if (communityFragment == null) {
communityFragment = new CommunityFragment();
Bundle bundle = new Bundle();
bundle.putString("community", "Community");
communityFragment.setArguments(bundle);
mFragments.add(communityFragment);
hideOthersFragment(communityFragment, true, "communityfragment");
} else {
hideOthersFragment(communityFragment, false, "communityfragment");
}
communityFragment.sendMessage(new ICommuntyCallBack() {
@Override
public void getMessageFromCommunty(String community) {
mTvMain.setText(community);
}
});
break;
case R.id.rb_message: //信息
if (messageFragment == null) {
messageFragment = new MessageFragment();
Bundle bundle = new Bundle();
bundle.putString("message", "Message");
messageFragment.setArguments(bundle);
mFragments.add(messageFragment);
hideOthersFragment(messageFragment, true, "messagefragment");
} else {
hideOthersFragment(messageFragment, false, "messagefragment");
}
break;
case R.id.rb_me: //我的
if (meFragment == null) {
meFragment = new MeFragment();
Bundle bundle = new Bundle();
bundle.putString("me", "Me");
meFragment.setArguments(bundle);
mFragments.add(meFragment);
hideOthersFragment(meFragment, true, "mefragment");
} else {
hideOthersFragment(meFragment, false, "mefragment");
}
meFragment.sendMessage(new IMeCallBack() {
@Override
public void getMessageFromMe(String me) {
mTvMain.setText(me);
}
});
break;
}
}
});
}
private void hideOthersFragment(Fragment showFragment, boolean add, String tag) {
mTransaction = mSupportFragmentManager.beginTransaction();
if (add) {
mTransaction.add(R.id.frameLayout, showFragment, tag);
//根据标记添加到回退栈
mTransaction.addToBackStack(tag);
Log.i("TAG", "当前添加的fragment是:" + tag);
}
for (Fragment fragment : mFragments) {
if (showFragment.equals(fragment)) {
mTransaction.show(fragment);
} else {
mTransaction.hide(fragment);
}
}
mTransaction.commit();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
int count = mSupportFragmentManager.getBackStackEntryCount();
Log.i("TAG", "获取当前回退栈中fragment的个数是:" + count);
if (count > 1) {
mSupportFragmentManager.popBackStackImmediate();//回退一步清除回退栈中栈顶Fragment
//获取当前退到了哪一个Fragment上,重新获取当前的Fragment回退栈中的个数
int currentCount = mSupportFragmentManager.getBackStackEntryCount() - 1;
Log.i("TAG", "剩余fragment个数是:" + currentCount);
FragmentManager.BackStackEntry backStackEntryAt = mSupportFragmentManager.getBackStackEntryAt(mSupportFragmentManager.getBackStackEntryCount()-1);
String tag = backStackEntryAt.getName();
Log.i("TAG", "当前栈顶的fragment:" + tag);
if ("homefragment".equals(tag)) {
mRbHome.setChecked(true);
} else if ("communityfragment".equals(tag)) {
mRbCommunity.setChecked(true);
} else if ("messagefragment".equals(tag)) {
mRbMessage.setChecked(true);
} else if ("mefragment".equals(tag)) {
mRbMe.setChecked(true);
}
//mSupportFragmentManager.popBackStackImmediate();//回退一步清除回退栈中栈顶Fragment
} else {
finish();//回退栈中只剩一个Fragment时,退出应用
}
}
return true;
}
}
退出其他所有的frament,只剩首页fragment:只需修改以下代码
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
int count = mSupportFragmentManager.getBackStackEntryCount();
//回退栈中至少有多个Fragment,栈底部是首页
if(count>1){
while(mSupportFragmentManager.getBackStackEntryCount()>1){
mSupportFragmentManager.popBackStackImmediate();
//选中第一个界面
mRbHome.setChecked(true);
}
}else{
finish();
}
return true;
}
在当前的fragment,点击返回键,直接退出整个activity
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
for (int i = 0; i < count; ++i) {
mSupportFragmentManager.popBackStack();
finish();
}
return true;
}