Как реализовать onBackPressed () во фрагментах? - PullRequest
391 голосов
/ 27 марта 2011

Есть ли способ, которым мы можем реализовать onBackPressed() в Android Fragment, аналогично тому, как мы реализуем в Android Activity?

Поскольку жизненный цикл фрагмента не имеет onBackPressed().Есть ли другой альтернативный метод для перегрузки onBackPressed() во фрагментах Android 3.0?

Ответы [ 40 ]

0 голосов
/ 18 февраля 2018

Если ваш фрагмент находится в действии (предположим, у вас есть действие, в этом действии вы используете FrameLayout, затем вызываете фрагмент A или B или C с помощью FrameLayout из вашего действия), тогда вы просто используете

getActivity().onBackPressed(); из вашего фрагмента.

0 голосов
/ 04 декабря 2013

Вот мое решение для этой проблемы:

в упражнении A:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
{
    super.onActivityResult(requestCode, resultCode, data);

    if(requestCode == REQUEST_CODE)
    {
        if(resultCode == Activity.RESULT_OK)
        {
            tvTitle.setText(data.getExtras().getString("title", ""));
        }
    }
}

в упражнении B:

@Override
public void onBackPressed() 
{
    setResult(Activity.RESULT_OK, getIntent());

    super.onBackPressed();
}

активность b содержит фрагмент.

во фрагменте:

private void setText(String text)
    {
        Intent intent = new Intent();
        intent.putExtra("title", text);
        getActivity().setIntent(intent);
    }

таким образом "данные" объекта намерений в действии A получат строку из фрагмента

0 голосов
/ 12 мая 2018
public interface IonBackPressInFrag {
    void backPressed();
}

public class FragmentMainActivity extends AppCompatActivity {
    public IonBackPressInFrag backPressInFrag;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        @Override
        public void onBackPressed () {
            backPressInFrag.backPressed();
        }
    }
}

public class FragDetailSearch extends Fragment implements IonBackPressInFrag {
 if(getActivity() !=null){
        ((FragmentMainActivity) getActivity()).backPressInFrag = this;
    }

    @Override
    public void backPressed() {
        Toast.makeText(getContext(), "backkkkkk", Toast.LENGTH_LONG).show();
    }
}
0 голосов
/ 22 марта 2018

Эта строка кода будет выполнять трюк из любого фрагмента, она вытолкнет текущий фрагмент в backstack.

getActivity().getSupportFragmentManager().popBackStack();
0 голосов
/ 20 марта 2014

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

1 - в вашей активности должен быть интерфейс слушателя и список слушателей

2 - Вы должны реализовать методы для добавления и удаления слушателей

3 - Вы должны переопределить метод onBackPressed, чтобы проверить, использует ли кто-либо из слушателей нажатие сзади или нет

public class MainActivity ... {

    /**
     * Back press listener list. Used for notifying fragments when onBackPressed called
     */
    private Stack<BackPressListener> backPressListeners = new Stack<BackPressListener>();


    ...

    /**
     * Adding new listener to back press listener stack
     * @param backPressListener
     */
    public void addBackPressListener(BackPressListener backPressListener) {
        backPressListeners.add(backPressListener);
    }

    /**
     * Removing the listener from back press listener stack
     * @param backPressListener
     */
    public void removeBackPressListener(BackPressListener backPressListener) {
        backPressListeners.remove(backPressListener);
    }


    // Overriding onBackPressed to check that is there any listener using this back press
    @Override
    public void onBackPressed() {

        // checks if is there any back press listeners use this press
        for(BackPressListener backPressListener : backPressListeners) {
            if(backPressListener.onBackPressed()) return;
        }

        // if not returns in the loop, calls super onBackPressed
        super.onBackPressed();
    }

}

4 -Ваш фрагмент должен реализовывать интерфейс для обратного нажатия

5 - Вам необходимо добавить фрагмент в качестве прослушивателя для обратного нажатия

6 - Вы должны вернуть true из onBackPressed, если фрагмент использует это обратное нажатие

7 - ВАЖНО - Вы должны удалить фрагмент из списка на Дестрой

public class MyFragment extends Fragment implements MainActivity.BackPressListener {


    ...

    @Override
    public void onAttach(Activity activity) {
        super.onCreate(savedInstanceState);

        // adding the fragment to listener list
        ((MainActivity) activity).addBackPressListener(this);
    }

    ...

    @Override
    public void onDestroy() {
        super.onDestroy();

        // removing the fragment from the listener list
        ((MainActivity) getActivity()).removeBackPressListener(this);
    }

    ...

    @Override
    public boolean onBackPressed() {

        // you should check that if this fragment is the currently used fragment or not
        // if this fragment is not used at the moment you should return false
        if(!isThisFragmentVisibleAtTheMoment) return false;

        if (isThisFragmentUsingBackPress) {
            // do what you need to do
            return true;
        }
        return false;
    }
}

Вместо ArrayList используется стек, чтобы можно было начинать с последнего фрагмента.Также может возникнуть проблема при добавлении фрагментов в задний стек.Таким образом, вы должны проверить, что фрагмент виден или нет при использовании обратного нажатия.В противном случае один из фрагментов будет использовать событие, и последний фрагмент не будет закрыт при обратном нажатии.

Надеюсь, это решит проблему для всех.

0 голосов
/ 13 марта 2018

Для реализации следующим образом Fragment_1 -> Fragment_2 -> Fragment_3

    Button btn = (Button) rootView.findViewById(R.id.your_button_id);
    btn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Fragment_2 nextFrag= new Fragment_2();
            getActivity().getSupportFragmentManager().beginTransaction()
                    .replace(R.id.content_frame, nextFrag,getTag())
                    .addToBackStack(null)
                    .commit();

        }
    });

Fragment_3 -> Fragment_2 -> Fragment_1

Step_1: создать общедоступную строку в базовой деятельности

Step_2: всякий раз, когда активируется новый фрагмент, измените значение строки в базовой активности

Step_3: затем добавьте метод onBackPressed () и передайте значение строки в другой метод, в котором можно заменить пометки

В базовом действии

public static String currentFragment=null;

@Override
public void onBackPressed() 
{
        displayPreviousFragment(currentFragment);
}

public void displayPreviousFragment(String currentFragment)
{
    //creating fragment object
    Fragment fragment = null;

    //initializing the fragment object which is selected
    switch (currentFragment)
    {
        case "Fragment_2"    :   fragment = new Fargment_1();     break;
        case "Fragment_3"    :   fragment = new Fragment_2();     break;
    }

    //replacing the fragment
    if (fragment != null) {
        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.frame_to_replace_fragment, fragment);
        ft.commit();
    }
}

Во Fragment_2 внутри метода OnCreateView

BaseActivity.currentFragment="Fragment_2";

Во Fragment_3 внутри метода OnCreateView

BaseActivity.currentFragment="Fragment_3";
0 голосов
/ 18 января 2018

Простой способ обработки onBackPressed () во фрагментах

Шаг 1: Создать статическое логическое значение в действии.

public static Fragment_one;

Шаг 2: На MainActivity (Activity, которая содержит фрагмент) в методе On Create, объявите

Fragment_one=true;

Шаг 3: Переопределить onBackPressed () в MainActivity

@Override
public void onBackPressed() {

    if(Fragment_one) {
     //Back key pressed on fragment one

    }else {
      //Back key pressed on fragment two
    }
}

Шаг 4: На фрагменте onCreateView метод объявить

MainActivity.Fragment_one=true;

Шаг 5 На фрагмент_два onCreateView метод объявить

MainActivity.Fragment_one=false;

Примечание: Этот метод может применяться только к ДВУМЯ фрагментам.

0 голосов
/ 30 ноября 2017

Фрагмент: Сделайте BaseFragment, поместив метод:

 public boolean onBackPressed();

Активность:

@Override
public void onBackPressed() {
    List<Fragment> fragments = getSupportFragmentManager().getFragments();
    if (fragments != null) {
        for (Fragment fragment : fragments) {
            if (!fragment.isVisible()) continue;

            if (fragment instanceof BaseFragment && ((BaseFragment) fragment).onBackPressed()) {
                return;
            }
        }
    }

    super.onBackPressed();
}

Ваша активность будет проходить по прикрепленным и видимым фрагментам и вызывать onBackPressed () для каждого из них и прерывать работу, если один из них возвращает «true» (что означает, что оно было обработано, поэтому дальнейших действий не требуется). действия).

0 голосов
/ 20 июня 2014

Я просто использую findFragmentById и приведу к фрагменту и вызову метод, который обрабатывает onBackpressed.В этом примере показана проверка того, является ли это первым шагом в процессе заказа, если всплывающий фрагмент диалога для подтверждения порядка выхода.

@Override
    public void onBackPressed() {
        //check if first fragment in wizard is loaded, if true get abandon confirmation before going back
        OrderFragment frag =(OrderFragment)getSupportFragmentManager().findFragmentById(R.id.fragContainer);
        if (frag==null || (frag!=null && frag.getOrderStage()<1)){
            AlertDialogFragment.show(getSupportFragmentManager(), R.string.dialog_cancel_order,R.string.dialog_cancel_order_msg, R.string.dialog_cancel_order_pos,R.string.dialog_order_quiz_neg, DIALOG_ID_CANCEL);
        }else {
            super.onBackPressed();
        }
    }
0 голосов
/ 29 августа 2017

на mainActivity

protected DrawerHomeActivity.OnBackPressedListener onBackPressedListener;

public interface OnBackPressedListener {
    void doBack();
}

public void setOnBackPressedListener(DrawerHomeActivity.OnBackPressedListener onBackPressedListener) {
    this.onBackPressedListener = onBackPressedListener;
}

@Override
public void onBackPressed() {
    if (onBackPressedListener != null) {
        onBackPressedListener.doBack();


    }
    else
        super.onBackPressed();



}

на фрагменте реализуют базовую активность / фрагмент, подобный

implements DrawerHomeActivity.OnBackPressedListener

DraweHomeActivity - моя базовая активность.

((DrawerHomeActivity) getActivity()).setOnBackPressedListener(this);

и создать метод doBack

@Override
public void doBack() {
    //call base fragment 
    }
...