Нажатие назад не возвращает к предыдущему фрагменту

У меня проблема с добавлением транзакций фрагментов в задний стек. У меня есть основное действие, в котором я заполняю свой макет фрагментом меню:

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

}

Насколько я понимаю, это должно сделать так, чтобы когда пользователь нажимал кнопку «Назад» на своем устройстве, он возвращался к фрагменту меню, но вместо этого закрывал приложение. Что я делаю не так?


person JamMaster    schedule 25.09.2014    source источник
comment
попробуйте добавить вместо замены trans.add(R.id.frag_container, new BasicSettingsFragment());   -  person Georgian Benetatos    schedule 26.09.2014
comment
Кроме того, я только что заметил, что при повороте экрана фрагмент меню вообще не удаляется, а просто скрывается. Когда я повернул свой телефон, он появился над BasicSettingsFragment. Добавление @GeorgianBenetatos только помещает новый фрагмент поверх предыдущего.   -  person JamMaster    schedule 26.09.2014
comment
Вы должны опубликовать полный код MainMenuFragment, все выглядит нормально.   -  person Georgian Benetatos    schedule 26.09.2014
comment
является ли frag_container макетом кадра внутри activity_main?   -  person Georgian Benetatos    schedule 26.09.2014
comment
@GeorgianBenetatos Я только что обновил пост полным кодом. frga_container действительно является FrameLayout, определенным в XML-файле activity_main.   -  person JamMaster    schedule 26.09.2014
comment
Ваш код представляет собой смесь, вы используете ActionBarActivity из appcompat, а не используете getSupportFragmentManager(), и импорт фрагментов должен быть appcompat, если вы решите его использовать. Если нет, используйте Activity вместо ActionBarActivity и простой импорт фрагментов с помощью FragmentManager.   -  person Georgian Benetatos    schedule 26.09.2014
comment
И поскольку вы используете активность только для показа фрагмента, сделайте activity_main.xml макетом фрейма, который вставит в него фрагмент!   -  person Georgian Benetatos    schedule 26.09.2014
comment
Спасибо! Это сработало. Но, к сожалению, без расширения ActionBarActivity у меня не может быть панели действий, и я не смог найти вариант библиотеки без поддержки.   -  person JamMaster    schedule 26.09.2014
comment
В Activiy есть панель действий, ActionBarActivity — это поддержка API уровня 2, вас обмануло название. Вы увидите, что существует другой вид поддержки действий, использующих фрагменты, называемый FragmentActivity, большинство из них устарело.   -  person Georgian Benetatos    schedule 26.09.2014
comment
На самом деле, я только что снова попытался повернуть свой телефон, и все еще кажется, что MainMenuFragment не удаляется при замене. Когда я поворачиваю, он появляется над моим BasicSettingsFragment точно так же, как и раньше.   -  person JamMaster    schedule 26.09.2014
comment
Давайте продолжим обсуждение в чате.   -  person Georgian Benetatos    schedule 26.09.2014
comment
На какие устройства вы ориентируетесь? В частности, какой уровень API? Если вы ориентируетесь на ‹ API 11, вам следует использовать ActionBarActivity. Если вы ориентируетесь на ›= API 11, вы можете просто использовать Activity.   -  person Code-Apprentice    schedule 26.09.2014


Ответы (4)


Ваш код представляет собой смесь, вы используете ActionBarActivity из appcompat, а не используете getSupportFragmentManager(), и импорт фрагментов должен быть appcompat, если вы решите его использовать. Если нет, используйте Activity вместо ActionBarActivity и простой импорт фрагментов с помощью FragmentManager.

Добавьте это в свою активность android:configChanges="keyboardHidden|orientation|screenSize" Это предотвратит перезапуск вашей активности при смене. используйте setRetainInstance(true) для фрагментов.

person Georgian Benetatos    schedule 25.09.2014
comment
Тогда вам, вероятно, следует призвать ОП опубликовать новый вопрос. - person Code-Apprentice; 26.09.2014

В Activity перезапишите:

@Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() > 0) {
        getFragmentManager().popBackStack();
    } else {
        super.onBackPressed();
    }
}

И, вероятно, вам нужно использовать в каждой зафиксированной транзакции фрагмента:

FragmentTransaction.addToBackStack(null);
person Adam Styrc    schedule 15.01.2015

Вы не добавляете MainMenuFragment в задний стек. Вы можете попробовать это в своей деятельности:

getFragmentManager().beginTransaction().add(
R.id.frag_container, new MainMenuFragment()).
addToBackStack(null).commit();
person S M Anagh    schedule 26.09.2014

Когда вы добавляете или заменяете фрагмент с помощью FragmentManager, вам необходимо вручную добавить старый фрагмент в стопку с помощью addToBackStack() перед вызовом commit().

person Code-Apprentice    schedule 25.09.2014
comment
Это то, что я делаю. Проблема в том, что когда я использую replace, он не удаляет старый фрагмент, потому что, когда я поворачиваю экран, он появляется поверх того, что было до поворота. - person JamMaster; 26.09.2014