替换两个不同的片段后,按下后退按钮时会重新创建第一个片段
Posted
技术标签:
【中文标题】替换两个不同的片段后,按下后退按钮时会重新创建第一个片段【英文标题】:After two different fragments have been replaced, first fragment is recreated when on pressed back button 【发布时间】:2016-12-01 08:20:29 【问题描述】:我有三个片段和一个活动。它是这样工作的:
[activity]-> [MainFragment]->[MenuFragment]->[SignUpFragment]
当[SignUpFragment]
被回按时,[MainFragment]
会被创建两次。
我尝试了setRetaInInstance(true)
并检查了savedInstanceState
,但我无法阻止[MainFragment]
重新创建。
这是我的 MainActivity:
public class MainActivity extends AppCompatActivity
public Bundle mSavedInstanceState;
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mSavedInstanceState = savedInstanceState;
setContentView(R.layout.activity_main);
@Override
protected void onResume()
super.onResume();
callMainFragment();
private void callMainFragment()
if (mSavedInstanceState == null)
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container_category, new MainFragment(), MainFragment.class.getSimpleName());
transaction.addToBackStack(null);
transaction.commit();
public ActionBar getMainActionBar()
ActionBar actionBar = getSupportActionBar();
if (actionBar != null)
// Action Bar Display settings
actionBar.setDisplayShowCustomEnabled(true);
actionBar.setDisplayShowTitleEnabled(false);
// Custom view inflater
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Custom layout view
View viewActionBar = inflater.inflate(R.layout.action_bar, null);
// Set custom view
actionBar.setCustomView(viewActionBar);
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
return actionBar;
这是我的 MainFragment:
public class MainFragment extends BaseFragment implements AdapterView.OnItemClickListener, BuyersGuideCategoriesDelegate, View.OnClickListener
private Bundle mSavedInstanceState;
private BuyersGuideCategoriesFragment mCategoriesFragment;
@Override
public void onCreate(@Nullable Bundle savedInstanceState)
super.onCreate(savedInstanceState);
this.setRetainInstance(true);
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
mSavedInstanceState = savedInstanceState;
if (mSavedInstanceState == null)
mView = inflater.inflate(R.layout.fragment_main, container, false);
// Call Grid View Buyers Guide Fragment
mCategoriesFragment = new BuyersGuideCategoriesFragment();
mCategoriesFragment.mGridViewDelegate = this;
setIcons();
setTitles();
setTexts();
initListView();
return mView;
@Override
public void onResume()
super.onResume();
ImageView menu = (ImageView) ((MainActivity) getActivity()).getMainActionBar().getCustomView().findViewById(R.id.action_bar_menu_icon);
menu.setOnClickListener(this);
@Override
public void onClick(View v)
if (mSavedInstanceState == null)
MainActivity activity = (MainActivity) getActivity();
FragmentManager manager = activity.getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.container_category, new MenuFragment(),MenuFragment.class.getSimpleName());
transaction.addToBackStack(null);
transaction.commit();
这是我的 MenuFragment:
public class MenuFragment extends BaseFragment implements AdapterView.OnItemClickListener, View.OnClickListener
private Bundle mSavedInstanceState;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
mSavedInstanceState = savedInstanceState;
if (savedInstanceState == null)
mView = inflater.inflate(R.layout.fragment_menu, container, false);
setMenuItemsListViewAdapter();
return mView;
private void setMenuItemsListViewAdapter()
ListView menuItems = (ListView) mView.findViewById(R.id.list_menu_items);
ListMenuItemsListViewAdapter adapter = new ListMenuItemsListViewAdapter(getContext(),getMenuItemNames());
menuItems.setAdapter(adapter);
menuItems.setOnItemClickListener(this);
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
switch ((String) parent.getAdapter().getItem(position))
case SIGN_UP:
replaceFragment(R.id.container_category,new SignUpFragment(),SignUpFragment.class.getSimpleName());
break;
private void replaceFragment(int containerId,Fragment fragment, String fragmentTag)
if (mSavedInstanceState == null)
MainActivity activity = (MainActivity) getActivity();
FragmentManager manager = activity.getSupportFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(containerId,fragment,fragmentTag);
transaction.addToBackStack(null);
transaction.commit();
@Override
public void onClick(View v)
switch (v.getId())
case R.id.menu_back_icon:
replaceFragment(R.id.container_category, new MainFragment(),MainFragment.class.getSimpleName());
break;
这是我的 SignUpFragment:
public class SignUpFragment extends BaseFragment implements View.OnClickListener
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
if (savedInstanceState == null)
mView = inflater.inflate(R.layout.fragment_sign_up, container, false);
return mView;
编辑 1:仅当我从 SignUpFragment 返回到 MenuFragment 时,才重新创建 MainFragment。使用这么多片段我做错了吗?我应该使用活动吗?
【问题讨论】:
请给我们一些代码。没有任何实际信息就无法为您提供帮助! 您是否有一个活动托管三个不同的片段? 是的,我正在使用单个活动。 【参考方案1】:当你在 Fragments 之间移动时,调用 addToBackStack() :
FragmentTransaction ft = fragmentManager.beginTransation();
ft.replace( R.id.fragment, new MyFragment() ).addToBackStack( "ftransaction" ).commit();
【讨论】:
【参考方案2】:创建第一个片段:
FragmentTransaction ft = fragmentManager.beginTransation();
ft.add(R.id.container, new FirstFragment()).addToBackStack(null).commit();
第二:
FragmentTransaction ft = fragmentManager.beginTransation();
ft.replace(R.id.container, new SecondFragment()).addToBackStack(null).commit();
第三个:
FragmentTransaction ft = fragmentManager.beginTransation();
ft.replace(R.id.container, new ThirdFragment()).commit();
【讨论】:
以上是关于替换两个不同的片段后,按下后退按钮时会重新创建第一个片段的主要内容,如果未能解决你的问题,请参考以下文章
在 Activity App Bar 上按下后转到带有它被调用的片段的父 Activity