替换两个不同的片段后,按下后​​退按钮时会重新创建第一个片段

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();

【讨论】:

以上是关于替换两个不同的片段后,按下后​​退按钮时会重新创建第一个片段的主要内容,如果未能解决你的问题,请参考以下文章

Kivy - 按下后更改按钮的颜色?

按下后退按钮时正在重新创建 Listview 片段

在 Activity App Bar 上按下后转到带有它被调用的片段的父 Activity

登录按钮按下后,如何获取Tkinter entry的值并传递给SQL查询?

恢复后停止重新创建片段?

labview 如何设置按钮按下后形状还原?