Кнопка возврата к фрагменту

Теперь у меня есть действие, содержащее фрагменты

[1], [2], [3], [4]

При нажатии кнопок [3] его можно перенаправить на [4]

Я хотел бы реализовать обратную кнопку, как показано ниже.

при нажатии на [4], он возвращается к [3]

при нажатии на [3], он возвращается к [2]

при нажатии на [1] активность завершается();

Когда дело доходит до текущей реализации, оно завершает работу вместо того, чтобы всплывать Фрагмент. Не могли бы вы рассказать мне, что я должен делать или иметь в виду?

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

    if( keyCode==KeyEvent.KEYCODE_BACK) 
    {   

        finish();
    }       

        return super.onKeyDown(keyCode, event); 

}   

Ответ 1

В вашем onCreate() в вашей деятельности, где содержатся ваши фрагменты, добавьте прослушиватель изменений в backstack следующим образом:

    fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
        @Override
        public void onBackStackChanged() {
            List<Fragment> f = fragmentManager.getFragments();
            Fragment frag = f.get(0);
            currentFragment = frag.getClass().getSimpleName();
        }
    });

(Nb. мой fragManager объявлен глобальным) Теперь каждый раз, когда вы меняете фрагмент, строка currentFragment станет именем текущего фрагмента. Затем в действиях onBackPressed() вы можете управлять действиями кнопки "Назад" следующим образом:

    @Override
    public void onBackPressed() {

    switch (currentFragment) {
        case "FragmentOne":
            // your code here 
            return;
        case "FragmentTwo":
            // your code here
            return;
        default:
            fragmentManager.popBackStack();
            // default action for any other fragment (return to previous)
    }

}

Я могу подтвердить, что этот метод работает для меня.

Ответ 2

Это сработало для меня.

-Add.addToBackStack(null), когда вы вызываете новый фрагмент из активности.

    FragmentTransaction mFragmentTransaction = getFragmentManager()
                .beginTransaction();
    ....
    mFragmentTransaction.addToBackStack(null);

-Добавить onBackPressed() к вашей активности

    @Override
public void onBackPressed() {
    if (getFragmentManager().getBackStackEntryCount() == 0) {
        this.finish();
    } else {
        getFragmentManager().popBackStack();
    }
}

Ответ 3

Самый простой способ:

onResume():

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

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button click listener
                Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
                return true;
            }
            return false;
        }
    });

}

Изменить 1: если фрагмент имеет EditText.

private EditText editText;

onCreateView():

editText = (EditText) rootView.findViewById(R.id.editText);

onResume():

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

    editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                editText.clearFocus();
            }
            return false;
        }
    });

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
                // handle back button click listener
                Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
                return true;
            }
            return false;
        }
    });

}

Примечание: Он будет работать, если в фрагменте EditText.

Готово

Ответ 4

Это работающее решение для меня:

dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
                    @Override
                    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                        if (keyCode == KeyEvent.KEYCODE_BACK) {
                            // DO WHAT YOU WANT ON BACK PRESSED
                            return true;
                        }
                        return false;
                    }
                });

Изменить: Вы можете заменить диалог getView() на фрагменты.

Ответ 5

Вы можете использовать это.. Работали для меня..

Кажется, что фрагмент [3] не удаляется из представления, когда нажата кнопка назад, поэтому вам нужно сделать это вручную!

Прежде всего, не используйте replace(), а вместо этого используйте remove и добавьте отдельно. Кажется, что replace() не работает должным образом.

Следующая часть этого метода переопределяет метод onKeyDown и удаляет текущий фрагмент каждый раз при нажатии кнопки "Назад".

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event)
 {
 if (keyCode == KeyEvent.KEYCODE_BACK)
 {
    if (getSupportFragmentManager().getBackStackEntryCount() == 0)
    {
        this.finish();
        return false;
    }
    else
    {
        getSupportFragmentManager().popBackStack();
        removeCurrentFragment();

        return false;
    }



 }

  return super.onKeyDown(keyCode, event);
 }


public void removeCurrentFragment()
{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

Fragment currentFrag =  getSupportFragmentManager().findFragmentById(R.id.f_id);
}

Ответ 6

Попробуйте это простое решение:

В вашей деятельности реализуется onBackPressed

 @Override
    public void onBackPressed() {
       if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
            getSupportFragmentManager().popBackStack();
        } else {
            finish();
        }
    }

Это будет работать, если вы хотите поместить верхний фрагмент на каждом обратном нажатии. Примечание: - При добавлении фрагмента в действие всегда добавляйте транзакцию в задний стек, чтобы это работало

Ответ 7

Еще лучше решить, как следовать шаблону проектирования, так что событие прессования на бэк-кнопках распространяется от активного фрагмента до главной операции. Итак, это похоже на то, что если один из активных фрагментов потребляет обратное нажатие, активность не будет действовать на него, и наоборот.

Один из способов сделать это состоит в том, чтобы все ваши фрагменты расширяли базовый фрагмент, который имеет абстрактный метод boolean onBackPressed().

@Override
public boolean onBackPressed() {
   if(some_condition)
      // Do something
      return true; //Back press consumed.
   } else {
      // Back-press not consumed. Let Activity handle it
      return false;
   }
}

Следите за активным фрагментом внутри своей деятельности и внутри него onBackPressed callback пишите что-то вроде этого

@Override
public void onBackPressed() {
   if(!activeFragment.onBackPressed())
      super.onBackPressed();
   }
}

Этот пост имеет этот шаблон, подробно описанный

Ответ 8

В этом случае я реализую функцию onBackPressed() из Activity:

@Override
public void onBackPressed() {
   super.onBackPressed();
   FragmentManager fm = getSupportFragmentManager();
   MyFragment myFragment = (MyFragment) fm.findFragmentById(R.id.my_fragment);

   if((myFragmen.isVisible()){
      //Do what you want to do
   }
}

Как это работает и для вас.

Ответ 9

Решение для нажатия или обратного вызова в фрагменте.

Как я решил свою проблему, я уверен, что это тоже поможет:

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

Здесь MainHomeFragment является основным фрагментом (когда я нажимаю кнопку со второго фрагмента, мне потребуется слишком MainHomeFragment)

    @Override
    public void onResume() {

    super.onResume();

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                MainHomeFragment mainHomeFragment = new SupplierHomeFragment();
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getActivity().getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, mainHomeFragment);
                fragmentTransaction.commit();

                return true;    
            }    
            return false;
        }
    }); }

2.Если у вас есть другой фрагмент с именем Somefragment и он имеет текстовое поле Edit, вы можете сделать это таким образом.

private EditText editText;

Тогда In,

onCreateView():    
editText = (EditText) view.findViewById(R.id.editText);

Затем переопределите OnResume,

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

    editText.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_BACK) {
                editTextOFS.clearFocus();
                getView().requestFocus();
            }
            return false;
        }
    });

    getView().setFocusableInTouchMode(true);
    getView().requestFocus();
    getView().setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {

            if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){

                MainHomeFragment mainHomeFragment = new SupplierHomeFragment();
                android.support.v4.app.FragmentTransaction fragmentTransaction =
                        getActivity().getSupportFragmentManager().beginTransaction();
                fragmentTransaction.replace(R.id.fragment_container, mainHomeFragment);
                fragmentTransaction.commit();

                return true;

            }

            return false;
        }
    });

}

Что все люди (amitamie.com):-); -)

Ответ 10

Вы можете использовать getFragmentManager().popBackStack() в базовом Fragment для возврата.

Ответ 11

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

webView.setOnKeyListener(new View.OnKeyListener(){

        @Override
        public boolean onKey(View view, int i, KeyEvent keyEvent) {
            if((i==KeyEvent.KEYCODE_BACK)&& webView.canGoBack()){
                webView.goBack();
                return true;
            }
            return false;
        }
    });

и импортировать этот класс

import android.view.KeyEvent;

Ответ 12

Вам также нужно проверить событие Action_Down или Action_UP. Если вы не будете проверять, то методKey() вызовет 2 раза.

getView().setFocusableInTouchMode(true);
getView().requestFocus();

getView().setOnKeyListener(new OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN) {
                    if (keyCode == KeyEvent.KEYCODE_BACK) {
                        Toast.makeText(getActivity(), "Back Pressed", Toast.LENGTH_SHORT).show();
                    return true;
                    }
                }
                return false;
            }
        });

Работаю очень хорошо для меня.

Ответ 13

Обязательно добавьте следующее:

if (event.getAction()!=KeyEvent.ACTION_DOWN)
                return true;

в блоке кода onKey, чтобы избежать вызова вызова дважды.

Ответ 14

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

 getSupportFragmentManager().beginTransaction().setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit).replace(R.id.content_frame, mContent, mContent.getClass().getSimpleName()).addToBackStack(null)
                .commit();

и для кнопки "Назад".

@Override
    public void onBackPressed() {
        // note: you can also use 'getSupportFragmentManager()'
        FragmentManager mgr = getSupportFragmentManager();
        if (mgr.getBackStackEntryCount() == 1) {
            // No backstack to pop, so calling super
            finish();
        } else {
            mgr.popBackStack();
        }
    }

Важно отметить, что я использую 1 для проверки getBackStackEntryCount, потому что, если вы его не используете и используете 0, пользователь не видит ничего для последней кнопки возврата.