按下返回键无法返回到上一个片段。

8

我遇到了将片段事务添加到返回堆栈的问题。我有一个主Activity,在其中使用Menu Fragment填充布局:

public class MainActivity extends ActionBarActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getFragmentManager().beginTransaction().add(R.id.frag_container, new MainMenuFragment()).commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}

接下来,在MainMenuFragment内,用户选择某个选项,导致菜单片段被替换为另一个片段:

public class MainMenuFragment extends Fragment implements OnItemClickListener{
    GridView grid;
    FragmentManager manager;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.main_menu_fragment, container, false);

    manager = getActivity().getFragmentManager();
    grid = (GridView) root.findViewById(R.id.gridView1);

    grid.setAdapter(new MenuTileAdapter(getActivity()));
    grid.setOnItemClickListener(this);

    return root;
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    FragmentTransaction trans = manager.beginTransaction();
    if (position == 0){
        trans.replace(R.id.frag_container, new BasicSettingsFragment());
        trans.addToBackStack(null);
        trans.commit();
    }
}

据我的理解,这应该使得当用户在设备上按下返回按钮时,会回到菜单片段,但实际上却退出了应用程序。我做错了什么?


我刚刚注意到当旋转屏幕时,菜单片段并没有被删除,只是隐藏了起来。当我旋转手机时,它出现在BasicSettingsFragment之上。@GeorgianBenetatos添加的新片段只是放在以前的片段之上。 - JamMaster
你应该发布完整的MainMenuFragment代码,一切看起来都很好。 - Georgian Benetatos
frag_container是activity_main中的一个FrameLayout吗? - Georgian Benetatos
@GeorgianBenetatos 我刚刚更新了帖子,附上了完整的代码。frga_container确实是在activity_main的XML文件中定义的FrameLayout。 - JamMaster
你的目标设备是什么?具体来说,你要使用哪个API级别?如果你的目标是小于API 11的设备,那么你应该使用ActionBarActivity。如果你的目标是大于或等于API 11的设备,那么你可以直接使用Activity。 - Code-Apprentice
显示剩余7条评论
4个回答

5
在您的Activity中进行重写:
@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

也许你需要在每个提交的片段事务中使用:

FragmentTransaction.addToBackStack(null);

2

你的代码混乱了,你使用了来自appcompat的ActionBarActivity,但没有使用getSupportFragmentManager(),如果你决定使用它,片段导入应该是appcompat的。如果不使用它,请使用Activity代替ActionBarActivity,以及带有FragmentManager的简单Fragment导入。

android:configChanges="keyboardHidden|orientation|screenSize"添加到你的活动中。这将阻止你旋转时活动重新启动。在片段上使用setRetainInstance(true)


你应该鼓励原帖作者发布一个新的问题。 - Code-Apprentice

1

您没有将MainMenuFragment添加到后退栈中。您可以在您的活动上尝试这个:

getFragmentManager().beginTransaction().add(
R.id.frag_container, new MainMenuFragment()).
addToBackStack(null).commit();

0

当您使用FragmentManager添加或替换片段时,需要在调用commit()之前手动使用addToBackStack()将旧片段添加到后退栈中。


这就是我正在做的事情。问题在于当我使用 replace 时,它并没有删除旧的片段,因为当我旋转屏幕时,它会出现在旋转之前的内容上方。 - JamMaster

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接