Кнопка возврата к фрагменту
Теперь у меня есть действие, содержащее фрагменты
[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, пользователь не видит ничего для последней кнопки возврата.