Как закрыть текущий фрагмент, используя кнопку как кнопку возврата?

89

Я пытаюсь закрыть текущий фрагмент с помощью Imagebutton.

Я нахожусь во фрагменте-A, и когда я нажимаю кнопку, он превратится во фрагмент-B.

И когда я нажимаю кнопку на фрагменте-B, он превратится в фрагмент-C и закроет фрагмент-B.

Если я нажму кнопку возврата во фрагменте-C, он вернется к фрагменту-A.

Код, который я пробовал, выглядит следующим образом

camera_album = (ImageButton) view.findViewById(R.id.camera_album);

camera_album.setOnClickListener(new Button.OnClickListener() {
    @Override
    public void onClick(View v) {

                    closefragment();
        Fragment fragment = FileBrowserFragment.newInstance(null, null, null) ;
        MainActivity.addFragment(LocalFileBrowserFragment.this, fragment) ;


    }
});

private void closefragment() {
    getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}

Когда я нажимаю кнопку «Назад» на фрагменте-B, он превращается в фрагмент-C.

Но когда я нажимаю кнопку «Назад» на фрагменте-C, он не возвращается к фрагменту-A. Он вернулся к пустому фону. Если я хочу вернуться к фрагменту-A, мне нужно еще раз нажать кнопку «Назад».

ТАК, похоже, не закрывает текущий фрагмент.

Как закончить текущий фрагмент как кнопку возврата в Android?

Вун
источник
Что это MainActivity.addFragment(LocalFileBrowserFragment.this, fragment)??. вам нужно добавить фрагмент в backstak и, соответственно, выскочить то же самое
Raghunandan
Добавлен фрагмент в функцию addFragment.
Вун
к чему добавить фрагмент и метод активности ??
Raghunandan
2
getActivity (). onBackPressed (); может это сделать
Вишванат Лекшманан

Ответы:

82

Из фрагмента A, чтобы перейти к B, замените A на B и используйте addToBackstack()раньше commit().

Теперь из фрагмента B, чтобы перейти к C, сначала используйте popBackStackImmediate(), это вернет A. Теперь замените A на C, как и в первой транзакции.

SD
источник
4
для usinf popStackImmediate (): -> getView (). setOnKeyListener (new View.OnKeyListener () {@Override публичное логическое значение onKey (View v, int keyCode, событие KeyEvent) {if (keyCode == KeyEvent.KEYCODE_BACK) {getActivity () .getSupportFragmentManager (). popBackStackImmediate (); return true;} return false;}});
Яш Агравал
134

Я меняю код с getActivity().getFragmentManager().beginTransaction().remove(this).commit();

к

getActivity().getFragmentManager().popBackStack();

И он может закрыть фрагмент.

Вун
источник
36
getActivity (). onBackPressed (); Thik это сделает то, что вы объяснили.
Вишванат Лекшманан,
5
@ suomi35 нет. Когда вам нужно переопределить onBackPressed (), вы столкнетесь с проблемами с такой реализацией
Le_Enot 01
Не кажется работает. в 2016 году в setNavigationOnClickListener не работает.
1
@ViswanathLekshmanan Я думаю, это должен быть ответ, а не комментарий. И принятый ответ вдобавок.
Франсиско Ромеро
1
Он также закрывает Activity! Требуется только закрытие фрагмента.
Zon
72

Для тех, кому нужно разобраться простым способом

Пытаться getActivity().onBackPressed();

Вишванат Лекшманан
источник
getActivity () может быть нулевым много раз.
Арпит Дж.
1
@ArpitJ. это только null до вызова onAttach (), фрагмент не может существовать без активности.
Тамим Аттафи
@TamimAttafi Верно, но я имел в виду такие случаи, как вращение или действие завершено, и по какой-то причине экземпляр фрагмента все еще существует, тогда он вернет null.
Arpit J.
popBackStack()и popBackStackImmediate()являются более прямыми способами извлечения самого верхнего фрагмента без имитации нажатия кнопки. Использование onBackPressed()триггеров OnBackPressedCallbacks; если в будущем вы захотите обрабатывать нажатия кнопки «Назад» специально, вам придется переключиться на popBackStack()/, popBackStackImmediate()чтобы не запускать обратные вызовы программно.
Нолан Эми
Вы помещаете этот код в метод onclick кнопки фрагмента.
Anon
6

getActivity().onBackPressedделает все, что вам нужно. Он автоматически вызывает метод onBackPressed в родительском действии .

Фаррух Хабибуллаев
источник
5

Это способ сделать это с помощью Kotlin, я создал кнопку в макете фрагмента, а затем установил onClickListner в onViewCreated.

согласно комментарию @ Viswanath-Lekshmanan

override fun onViewCreated(view: View?, savedInstanceState: Bundle?) 
{
     super.onViewCreated(view, savedInstanceState)

     btn_FragSP_back.setOnClickListener {
        activity?.onBackPressed()
    }
}
Абдул Рехман
источник
закрывает действие, а не фрагмент
ниббана
4

Попробуй это:

ft.addToBackStack(null);   // ft is FragmentTransaction

Таким образом, когда вы нажимаете клавишу возврата , текущее действие (которое содержит несколько фрагментов) загружает предыдущий фрагмент, а не завершает само себя.

Шайлендра Мадда
источник
4

Попробуй это:

public void removeFragment(Fragment fragment){
    android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
    android.support.v4.app.FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    fragmentTransaction.remove(fragment);
    fragmentTransaction.commit();
}
Никто
источник
4

Вы можете попробовать эту логику, потому что она у меня работает.

frag_profile profile_fragment = new frag_profile();

boolean flag = false;
@SuppressLint("ResourceType")
public void profile_Frag(){
    if (flag == false) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        manager.getBackStackEntryCount();
        transaction.setCustomAnimations(R.anim.transition_anim0, R.anim.transition_anim1);
        transaction.replace(R.id.parentPanel, profile_fragment, "FirstFragment");
        transaction.commit();
        flag = true;
    }

}

@Override
public void onBackPressed() {
    if (flag == true) {
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();
        manager.getBackStackEntryCount();
        transaction.remove(profile_fragment);
        transaction.commit();
        flag = false;
    }
    else super.onBackPressed();
}
Рахул Ратор
источник
3
Button ok= view.findViewById(R.id.btSettingOK);
Fragment me=this;
ok.setOnClickListener( new View.OnClickListener(){
    public void onClick(View v){
     getActivity().getFragmentManager().beginTransaction().remove(me).commit();
    }
});
Бруно Л.
источник
3
Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, улучшает его долгосрочную ценность.
rollstuhlfahrer 03
1
Этот простой код фактически удаляет текущее представление фрагмента с помощью кнопки OK или Close на нем. Я использую его для выхода из панели настройки освещения, отображаемой как фрагмент, и возврата в действие. Извините за этот трюк, но под Android 8 я думаю, что управлять несколькими фрагментами не так практично.
Бруно Л.
1

Если вам нужно обработать действие более конкретно с помощью кнопки возврата, вы можете использовать следующий метод:

view.setFocusableInTouchMode(true);
view.requestFocus();
view.setOnKeyListener(new View.OnKeyListener() {
    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if( keyCode == KeyEvent.KEYCODE_BACK )
        {
            onCloseFragment();
            return true;
        } else {
            return false;
        }
    }
});
Мортеза Джаламбадани
источник
0

В своих фрагментах onCreateView(...)вы можете удалить представление, позвонив container.removeView(view);. Поэтому, если вы хотите удалить фрагмент, viewдолжно быть возвращаемое значение onCreateView,

например

    public View onCreateView(...){
        final View view = inflater.inflate(R.layout.your_fragments_layout,container,false);
        //Do something
        finishButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                container.removeView(view);
            }
        });
        return view;
    }
Ilmard
источник
0

если тебе нужно в 2020 году

    Objects.requireNonNull(getActivity()).onBackPressed();
Croid
источник
-8

Попробуй это

getActivity().finish();
Каран Чунара
источник
1
Попробуйте объяснить свой ответ подробнее, чтобы OP и другие люди могли понять ответ, который вернется к этому вопросу в будущем
Аман Чхабра,
7
это закрывает все действие, а не фрагмент
busuu
Мне это помогло. Те, кому нужна дополнительная информация, могут погуглить. Не нужно копировать сюда официальную документацию.
Alesha170
Если вы используете BottomNavigationView, который обычно имеет одно действие, эта команда закроет приложение, а не вернется к предыдущему фрагменту.
Aliton Oliveira