I want to handle the back press event when showing a popup window in android.
I do like this.
In the fragment:
#Override
public boolean onBackPressed() {
if (backPressStrategy == BACK_PRESS_PLAN_A) {
if (guideDialog != null) {
guideDialog.dismiss();
}
closeFlashPay(REQ_CLOSE_FLASH_PAY_AND_FINISH);
return true;
} else if (backPressStrategy == BACK_PRESS_PLAN_B) {
if (guideDialog != null) {
guideDialog.dismiss();
}
getActivity().finish();
return true;
} else {
return false;
}
}
And in the Activity, I do like this
#Override
public void onBackPressed() {
PayBaseFragment contentFragment = (PayBaseFragment) getSupportFragmentManager().findFragmentByTag(TAG_CONTENT_FRAGMENT);
if (contentFragment != null && contentFragment.onBackPressed()) {
return;
}
super.onBackPressed();
}
The problem is, the first time when I pressed back button, the popupwindow just disappeared and the override onBackPressed method was not invoked. Unless I press back button two times.
I show my popup window like this
guideDialog.showAtLocation(getActivity().getWindow().getDecorView(), Gravity.CENTER, 0, 0);
Thanks for help
You need to handle the back button key of your dialog with this :
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
#Override
public boolean onKey(DialogInterface arg0, int keyCode,
KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
dialog.dismiss();
// you can call your onBackPress here
}
return true;
}
});
Related
I'd like to use the BackButton in Fragments. I'm using this code to handle backbutton:
#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){
if (idozit.num > 0) {
if (!pmenu.pauseopen) {
pmenu.BeingPaused(idozit.idozitomegy,nextlevel,0);
} else {
pmenu.continuegame();
}
}
if (idozit.num == 0) {
idozit.numnull(db);
}
//Toast.makeText(getActivity(), "hello1", Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
});
}
When I click on BackButton this code works fine BUT if click on the BackButton again the app calls the onBackPressed method from MainActivity. I don't know why but if I'm using only a Toast or Log.d something like that in the onKey method then I'm able to click it again.
I'd like to say that pmenu is a simple class which is only stops music,make things gone etc. It's seems like somehow I always stuck in that class .
Have you any idea what am I doing wrong?
A cleaner solution is to make an Interface implemented by every fragment with a method called onBackPressed() like this:
public interface FragmentInterface {
void onBackPressed();
}
Then, you override the onBackPressed in yout activity calling your current fragment's onBackPressed (I'm assuming that you have a method to get your currentFragment)
#Override
public void onBackPressed(){
FragmentInterface currentfragment = getCurrentFragment();
currentfragment.onBackPressed();
}
Of course, in your fragment, implemented method should look like this:
#Override
public void onBackPressed() {
if (idozit.num > 0) {
if (!pmenu.pauseopen) {
pmenu.BeingPaused(idozit.idozitomegy,nextlevel,0);
} else {
pmenu.continuegame();
}
}
if (idozit.num == 0) {
idozit.numnull(db);
}
//Toast.makeText(getActivity(), "hello1", Toast.LENGTH_SHORT).show();
}
Replace false in last line with true and there's no need for return true before the last one
I use simple sidebar drawer and i want when user back pressed if drawer open close and when close activity finish. This library have not this function default. I use below code but not work :(
final SimpleSideDrawer mSlidingMenu = new SimpleSideDrawer( mactivity );
mSlidingMenu.setLeftBehindContentView(R.layout.sidebar);
mSlidingMenu.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
mSlidingMenu.closeLeftSide();
return true;
} else
return false;
}
});
toggleDrawer() method can be used to toggle between opening and closing of the drawer. So pair it up with onBackPressed() method to close the drawer while pressing back button.
#Override
public void onBackPressed() {
mSlidingMenu.toggleDrawer();
}
#Override
public void onBackPressed() {
if(mSlidingMenu.isClosed())
{
super.onBackPressed();
}
else
{
mSlidingMenu.closeLeftSide();
}
}
How to disable back button pressed for webview in android ?
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (wv1 != null && (keyCode == KeyEvent.KEYCODE_BACK)
&& wv1.canGoBack() )
{
wv1.goBack();
}
return true;
}
If you want to disable back button action when the WebView Visible and enable back button action if the WebView in not Visible try the below code in your Activity
#Override
public void onBackPressed() {
if(webview.getVisibility()==View.VISIBLE){
// dont pass back button action
if(webview.canGoBack()){
webview.goBack();
}
return;
}else{
// pass back button action
super.onBackPressed();
}
}
Simply override the onBackPressed() method.
#Override
public void onBackPressed() { }
Please try this
#Override
public void onBackPressed() {
if(webview.canGoBack()){
webview.goBack();
}
else{
super.onBackPressed();
}
}
There are many ways to make it,
Solution 1, overriding dispatchKeyEvent()
dispatchKeyEvent()(API Level 1, Android 1.0)
Refer to my answer use dispatchKeyEvent to disable back button
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
// TODO Auto-generated method stub
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
return true;
}
return super.dispatchKeyEvent(event);
}
Solution 2, overriding onBackPressed()
onBackPressed() (API Level 5, Android 2.0)
Refer to Use onBackPressed() to disable back button
#Override
public void onBackPressed() {
}
Solution 3, overriding onKeyDown()
onKeyDown() (API Level 1, Android 1.0)
Refer to Use onKeyDown() to disable back button
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
//preventing default implementation previous to android.os.Build.VERSION_CODES.ECLAIR
return true;
}
return super.onKeyDown(keyCode, event);
}
You have add below code in Activity for disable activity back pressed
#Override
public void onBackPressed() {
}
Add this below code in java file :
WebView mwebView;
Button backButton1;
backButton1 = findViewById(R.id.backButton1);
mwebView = findViewById(R.id.mwebView);
backButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mWebView.destroy();
}
});
My application has an activity with so many fragments. I want to disable the back button press in some fragment. I tried with the below code. But it doesn't work.
In the main activity:
#Override
public void onBackPressed() {
super.onBackPressed();
OrderFragment.onBackPress();
}
In the fragment,
public static void onBackPressed()
{
Log.d(TAG,"It listen");
}
I have the log message but, how can I disable the back button from my fragment.
You should keep a reference to the fragment you want to disable/handle back press event on your main activity:
class MainActivity{
OrderFragment mOrderFragment;
#Override
public void onBackPressed() {
if(mOrderFragment.isVisible())
mOrderFragment.onBackPressed();
else
super.onBackPressed();
}
}
In OrderFragment:
public void onBackPressed() {
//handle back press event
}
In your oncreateView() method you need to write this code and in KEYCODE_BACk return should true then it will stop the back button option for particular fragment
View v = inflater.inflate(R.layout.xyz, container, false);
//Back pressed Logic for fragment
v.setFocusableInTouchMode(true);
v.requestFocus();
v.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
}
return false;
}
});
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if( keyCode == KeyEvent.KEYCODE_BACK ) {
// leave this blank in order to disable the back press
return true;
} else {
return false;
}
}
});
I think you have to Override onResume method in fragments which you need to disable the back press.Tryout the following code.
#Override
public void onResume() {
super.onResume();
this.getView().setFocusableInTouchMode(true);
this.getView().requestFocus();
this.getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
return true;
}
return false;
}
});
}
Have you tried like this, Actually it works for me before.
you can set listener for Back key. if you add it, i guess it works.
youfragment.getView().setOnKeyListener( new OnKeyListener()
{
#Override
public boolean onKey( View v, int keyCode, KeyEvent event )
{
if( keyCode == KeyEvent.KEYCODE_BACK )
{
return true;
}
return false;
}
}
);
super.onBackPressed in the activity is the default implementation. Remove this if you don't want it.
I know this is an old question and because of navigation components and new ways this situation rarely occurs, still, maybe my answer helps someone.
I came across a similar situation where I needed the back button to be disabled and I couldn't change the activity as well. So in a fragment, I added this code block.
Language: Kotlin
override fun onResume() {
super.onResume()
this.requireView().isFocusableInTouchMode = true
this.requireView().requestFocus()
this.requireView().setOnKeyListener { _, keyCode, _ ->
keyCode == KeyEvent.KEYCODE_BACK
}
}
This will disable your back press on that specific fragment
#Override
public void onBackPressed() {
Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.fragment_container);
if (currentFragment instanceof YourFragment) {
currentFragment.onBackPressed();
} else
super.onBackPressed();
}
override fun onBackPressed() {
val currentFragment = findNavController(R.id.nav_host_fragment).currentDestination?.id
if (currentFragment == R.id.YourFragment) {
return
}
super.onBackPressed()
If you don't want your fragment to be in the backstack you can do so, by not adding it to the backstack in the transaction. So do NOT call FragmentTransaction.addToBackStack(); on the fragments you do not want in your backstack.
onBackPressed works like this:
public void More onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}
}
Thus when you call super.onBackPressed() you pop the BackStack before finishing the activity. The best way to sort this out is to make sure you do not add the fragments to the BackStack. It is normally done like this:
fragmentTransaction.addToBackStack(TAG);
An alternative solution, but uglier since you have still useless code left, would be making onBackPressed() directly call finish() to end the activity.
I would strongly advise you not use getView().setOnKeyListener(...) since it is code smell.
Try this
public void onBackPressed() {
if (!mFragments.popBackStackImmediate()) {
finish();
}else{
super.onBackPressed();}
}
I am now having an activity containing fragments
[1] , [2] , [3] , [4]
If pressing buttons , [3] , it can be redirected to [4]
I would like to implement the back button as shown follow..
when pressing back at [4] , it return to [3]
when pressing back at [3] , it return to [2]
when pressing back at [1] , the activity finishes();
When it comes to the current implementation, it finish the activity instead of popping up the Fragment. Would you please tell me what I should do or keep in mind ?
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if( keyCode==KeyEvent.KEYCODE_BACK)
{
finish();
}
return super.onKeyDown(keyCode, event);
}
This worked for me.
-Add .addToBackStack(null) when you call the new fragment from activity.
FragmentTransaction mFragmentTransaction = getFragmentManager()
.beginTransaction();
....
mFragmentTransaction.addToBackStack(null);
-Add onBackPressed() to your activity
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() == 0) {
this.finish();
} else {
getFragmentManager().popBackStack();
}
}
Easiest way ever:
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;
}
});
}
Edit 1: If fragment having 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;
}
});
}
Note: It will work if you have EditText in fragment.
Done
This is a working solution for me:
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: You can replace dialog with getView() for fragments.
Try this simple solution:
In your activity implement onBackPressed
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
}
This will work if you want to pop the top fragment on each back press.
Note:- While adding fragment to activity always do add the transaction to back stack for this to work
In your onCreate() in your activity housing your fragments add a backstack change listener like so:
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
List<Fragment> f = fragmentManager.getFragments();
Fragment frag = f.get(0);
currentFragment = frag.getClass().getSimpleName();
}
});
(Nb. my fragmentManager is declared global)
Now every time you change fragment the currentFragment String will become the name of the current fragment. Then in the activities onBackPressed() you can control the actions of your back button as so:
#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)
}
}
I can confirm that this method works for me.
Update : Kotlin
override fun onBackPressed() {
when(supportFragmentManager.fragments[0].javaClass.simpleName){
"FragmentOne" -> doActionOne()
"FragmentTwo" -> doActionTwo()
else -> supportFragmentManager.popBackStack()
}
}
Solution for Pressing or handling back button in Fragment.
The way I solved my issue I am sure it will helps you too:
1.If you don't have any Edit Text-box in your fragment you can use below code
Here MainHomeFragment is main Fragment (When I press back button from second fragment it will take me too 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.If you have another fragment named as Somefragment and it has Edit text-box then you can do it by this way.
private EditText editText;
Then In,
onCreateView():
editText = (EditText) view.findViewById(R.id.editText);
Then Override 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;
}
});
}
That's all folks (amitamie.com) :-) ;-)
Still better solution could be to follow a design pattern such that the back-button press event gets propagated from active fragment down to host Activity. So, it's like.. if one of the active fragments consume the back-press, the Activity wouldn't get to act upon it, and vice-versa.
One way to do it is to have all your Fragments extend a base fragment that has an abstract 'boolean onBackPressed()' method.
#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;
}
}
Keep track of active fragment inside your Activity and inside it's onBackPressed callback write something like this
#Override
public void onBackPressed() {
if(!activeFragment.onBackPressed())
super.onBackPressed();
}
}
This post has this pattern described in detail
What I do in this cases is I implement the onBackPressed() function from the 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
}
}
How this works for you too.
if you are using webview inside a fragment than use this in your onCreateView method
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;
}
});
and import this class
import android.view.KeyEvent;
You can use getFragmentManager().popBackStack() in basic Fragment to go back.
You also need to check Action_Down or Action_UP event. If you will not check then onKey() Method will call 2 times.
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;
}
});
Working very well for me.
you can use this one in onCreateView, you can use transaction or replace
OnBackPressedCallback callback = new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
//what you want to do
}
};
requireActivity().getOnBackPressedDispatcher().addCallback(this, callback);
Make sure to add the following:
if (event.getAction()!=KeyEvent.ACTION_DOWN)
return true;
in the onKey block of code to avoid the event calling twice.
i use a methode to change fragments it has thw following code
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();
and for the back button this .
#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();
}
}
the important thing to note is i use 1 for checking getBackStackEntryCount this is because if you dont use it and use 0 user sees nothing for the last back button.
use this (in kotlin)
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
override fun handleOnBackPressed() {
// in here you can do logic when backPress is clicked
}
})
i think this is the most elegant way to do it
Try this, its helped me :)
#Override
public void onResume() { //Pressed return button - returns to the results menu
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) {
/*Here your code*/
return true;
}
return false;
}
});
}
just paste it in your activity main
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
} else {
finish();
}
}