Фрагмент нажатие кнопки Назад
теперь у меня есть действие, содержащее фрагменты
[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);
}
14 ответов
хорошо, ребята, я, наконец, нашел хорошее решение.
в вашем 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();
}
});
(также добавление моего fragmenManager объявлено глобальным) Теперь каждый раз, когда вы меняете фрагмент, текущая строка фрагмента становится именем текущего фрагмента. Затем в activities onBackPressed () вы можете управлять действиями кнопки "Назад" следующим образом:
@Override
public void onBackPressed() {
switch (currentFragment) {
case "FragmentOne":
// your code here (Maybe dialog)
return;
case "FragmentTwo":
// your code here
return;
default:
fragmentManager.popBackStack();
// default action for any other fragment (return to previous)
}
}
Я могу подтвердить, что этот метод работает для меня.
это работает для меня.
-добавить .addToBackStack (null) при вызове нового фрагмента из действия.
FragmentTransaction mFragmentTransaction = getFragmentManager()
.beginTransaction();
....
mFragmentTransaction.addToBackStack(null);
- добавьте onBackPressed () в свою активность
@Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
самый простой способ когда-либо:
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's 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's click listener
Toast.makeText(getActivity(), "Back press", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
}
Примечание: он будет работать, если у вас есть полей EditText фрагмент.
сделал
это рабочее решение для меня:
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;
}
});
Edit: вы можете заменить диалог на getView()
фрагментов.
вы можете использовать это .. Работать на меня..
Кажется, что фрагмент [3] не удаляется из вида при нажатии назад, поэтому вам нужно сделать это вручную!
прежде всего, не используйте replace (), а вместо этого используйте remove и add отдельно. Кажется, что 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);
}
попробуйте это простое решение:
в вашей деятельности, реализации onBackPressed
@Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
}
Это будет работать, если вы хотите поп верхний фрагмент на каждой задней прессе. Примечание: - при добавлении фрагмента в действие всегда добавляйте транзакцию в задний стек, чтобы это работало
еще лучшим решением может быть следовать шаблону дизайна, чтобы событие нажатия кнопки "Назад" распространялось от активного фрагмента до активности хоста. Таким образом, это, как.. если один из активных фрагментов потребляет задний пресс, активность не будет действовать на него, и наоборот.
один из способов сделать это-заставить все ваши фрагменты расширить базовый фрагмент, который имеет абстрактный метод " 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();
}
}
этот пост имеет этот шаблон, описанный подробно
что я делаю в этом случае, я реализую функцию onBackPressed () из действия:
@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
}
}
Как это работает для вас тоже.
решение для нажатия или обработки кнопки Назад в фрагменте.
то, как я решил свою проблему, я уверен, что это поможет вам тоже:
1.Если у вас нет текстового поля редактирования в вашем фрагменте, вы можете использовать ниже code
здесь 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;
Потом В
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): -); -)
вам также нужно проверить событие Action_Down или Action_UP. Если вы не будете проверять, то метод onKey () вызовет 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;
}
});
работает очень хорошо для меня.
обязательно добавьте следующее:
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
в блоке onKey кода, чтобы избежать вызова события дважды.
Если вы используете webview внутри фрагмента, чем использовать это в методе 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;
Я использую метод для изменения фрагментов, он имеет thw следующий код
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, пользователь ничего не видит для последней кнопки "Назад".